diff --git a/slsDetectorSoftware/.gitignore b/slsDetectorSoftware/.gitignore new file mode 100644 index 000000000..752a00776 --- /dev/null +++ b/slsDetectorSoftware/.gitignore @@ -0,0 +1,3 @@ +*.o +*~ +#*# \ No newline at end of file diff --git a/slsDetectorSoftware/Makefile b/slsDetectorSoftware/Makefile new file mode 100644 index 000000000..17422ee95 --- /dev/null +++ b/slsDetectorSoftware/Makefile @@ -0,0 +1,96 @@ +include ../Makefile.include + +DESTDIR ?= ../bin +LIBDIR ?= $(DESTDIR) +DOCDIR ?= docs + + +CFLAGS= -g -DC_ONLY -fPIC +#FLAGS+= #-DVERBOSE -DVERYVERBOSE + +DFLAGS= -g -DDACS_INT + +INCLUDES?= -IcommonFiles -IslsDetector -I../slsReceiverSoftware/MySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -I../slsReceiverSoftware/include -IthreadFiles -I$(ASM) + +#EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -Wl,-R/usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -lca -lCom + + +SRC_CLNT=slsDetectorAnalysis/fileIO.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsDetector/slsDetectorUsers.cpp threadFiles/CondVar.cpp threadFiles/Mutex.cpp threadFiles/ThreadPool.cpp #../slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp + + +$(info ) +$(info #######################################) +$(info # Compiling slsDetectorSoftware #) +$(info #######################################) +$(info ) + + + + +OBJS = $(SRC_CLNT:.cpp=.o) + +.PHONY: all intdoc doc htmldoc package clean + +all: package $(SRC_CLNT) + +intdoc: $(SRC_H) $(SRC_CLNT) + doxygen doxy.config + +doc: $(DOCDIR)/pdf/slsDetectorUsersDocs.pdf + +$(DOCDIR)/pdf/slsDetectorUsersDocs.pdf: slsDetectorUsersDocs + cd slsDetectorUsersDocs/latex && make + $(shell test -d $(DOCDIR) || mkdir -p $(DOCDIR)) + $(shell test -d $(DOCDIR)/pdf || mkdir -p $(DOCDIR)/pdf) + cp slsDetectorUsersDocs/latex/refman.pdf $(DOCDIR)/pdf/slsDetectorUsersDocs.pdf + + +htmldoc: $(DOCDIR)/html/slsDetectorUsersDocs + +$(DOCDIR)/html/slsDetectorUsersDocs: slsDetectorUsersDocs + $(shell test -d $(DOCDIR) || mkdir -p $(DOCDIR)) + $(shell test -d $(DOCDIR)/html || mkdir -p $(DOCDIR)/html) + $(shell test -d $(DOCDIR)/html/slsDetectorUsersDocs && rm -r $(DOCDIR)/html/slsDetectorUsersDocs) + cp -r slsDetectorUsersDocs/html $(DOCDIR)/html/slsDetectorUsersDocs + +slsDetectorUsersDocs: slsDetectorUsers.doxy slsDetector/slsDetectorUsers.h slsDetector/slsDetectorUsers.cpp slsDetectorAnalysis/detectorData.h + doxygen slsDetectorUsers.doxy + + +mythenVirtualServer: $(SRC_MYTHEN_SVC) + cd mythenDetectorServer && make -f Makefile.virtual DESTDIR=$(DESTDIR) + +gotthardVirtualServer: $(SRC_MYTHEN_SVC) + cd gotthardDetectorServer && make -f Makefile.virtual DESTDIR=$(DESTDIR) + + + +%.o : %.cpp %.h Makefile + $(CXX) -o $@ -c $< $(INCLUDES) $(DFLAGS) -fPIC $(EPICSFLAGS) -lpthread #$(FLAGS) + + +package: $(OBJS) $(DESTDIR)/libSlsDetector.so $(DESTDIR)/libSlsDetector.a + + +$(DESTDIR)/libSlsDetector.so: $(OBJS) + $(CXX) -shared -Wl,-soname,libSlsDetector.so -o libSlsDetector.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64 -lpthread + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + mv libSlsDetector.so $(DESTDIR) + +$(DESTDIR)/libSlsDetector.a: $(OBJS) + ar rcs libSlsDetector.a $(OBJS) + mv libSlsDetector.a $(DESTDIR) + +clean: + rm -rf $(DESTDIR)/libSlsDetector.a $(DESTDIR)/libSlsDetector.so core docs/* slsDetectorUsersDocs $(OBJS) + cd + +#------------------------------------------------------------------------------- + +install: package + +install_inc: + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + cp -P slsDetector/slsDetectorUsers.h slsDetectorAnalysis/detectorData.h $(DESTDIR) + + diff --git a/slsDetectorSoftware/Makefile.Standalone b/slsDetectorSoftware/Makefile.Standalone new file mode 100644 index 000000000..d9a7c0868 --- /dev/null +++ b/slsDetectorSoftware/Makefile.Standalone @@ -0,0 +1,68 @@ +CFLAGS= -DC_ONLY +#FLAGS= -DVERBOSE -DVERYVERBOSE +INCLUDES= -IcommonFiles -IslsDetector -IMySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis + +#EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/SL5-x86/ -Wl,-R/usr/local/epics/base/lib/SL5-x86 -lca -lCom +CC=gcc +CXX=g++ + +SRC_CLNT= slsDetectorAnalysis/FileIO_Standalone.cpp MySocketTCP/MySocketTCP.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/AngularConversion_Standalone.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessingFileIO_Standalone.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp + +OBJS = $(SRC_CLNT:.cpp=.o) + +HEADERS = $(SRC_CLNT:.cpp=.h) commonFiles/sls_detector_defs.h slsDetectorAnalysis/detectorData.h slsDetector/slsDetectorBase.h slsDetector/slsDetectorUsers.h multiSlsDetector/multiSlsDetectorCommand.h + + + +SRC_MYTHEN_SVC = mythenDetectorServer/server.c mythenDetectorServer/server_funcs.c mythenDetectorServer/communication_funcs.c mythenDetectorServer/firmware_funcs.c mythenDetectorServer/mcb_funcs.c mythenDetectorServer/trimming_funcs.c + +all: package $(SRC_CLNT) + echo "compiling all" + +doc: $(SRC_H) $(SRC_CLNT) + doxygen doxy.config + + + +mythenServer: $(SRC_MYTHEN_SVC) + $(CC) $(SRC_MYTHEN_SVC) $(CFLAGS) $(FLAGS) $(INCLUDES) -ImythenDetectorServer -DVIRTUAL -lm -D MCB_FUNCS -DC_ONLY -DVERBOSE + mv a.out mythenServer + + +picassoServer: $(SRC_MYTHEN_SVC) + $(CC) $(SRC_MYTHEN_SVC) $(CFLAGS) $(FLAGS) $(INCLUDES) -ImythenDetectorServer -D VIRTUAL -lm -DMCB_FUNCS -DPICASSOD -DC_ONLY + mv a.out picassoServer + + + + + +%.o : %.cpp %.h + $(CXX) -Wall -o $@ -c $< $(INCLUDES) $(FLAGS) $(EPICSFLAGS) + + +package: $(OBJS) + $(CXX) -shared -Wl,-soname,libSlsDetector.so -o libSlsDetector.so $(OBJS) -lc $(INCLUDES) $(FLAGS) $(EPICSFLAGS) + ar rcs libSlsDetector.a $(OBJS) + +clean: + rm -rf libSlsDetector.a libSlsDetector.so core docs/* $(OBJS) + + +#------------------------------------------------------------------------------- +lib: package + + +# added install target, HBl +install_lib: lib + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + cp -P libSlsDetector.so $(DESTDIR) + +install_inc: + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + cp -P $(HEADERS) $(DESTDIR) + + +install_doc: doc + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + cp -Pr docs/* $(DESTDIR) diff --git a/slsDetectorSoftware/Makefile.x04sa b/slsDetectorSoftware/Makefile.x04sa new file mode 100644 index 000000000..59755550f --- /dev/null +++ b/slsDetectorSoftware/Makefile.x04sa @@ -0,0 +1,87 @@ +CFLAGS= -DC_ONLY -fPIC +#FLAGS+= #-DVERBOSE -DVERYVERBOSE + +DFLAGS= -DDACS_INT -DTHIS_PATH='"$(shell pwd)"' -DSLS_RECEIVER_FUNCTION_LIST + +#ASM=$(shell echo "/lib/modules/`uname -r`/build/include") + +INCLUDES?= -IcommonFiles -IslsDetector -IMySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -IslsReceiver -I$(ASM) + +EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/SL5-x86/ -Wl,-R/usr/local/epics/base/lib/SL5-x86 -lca -lCom +CC=g++ + + +SRC_CLNT= slsDetectorAnalysis/fileIO.cpp MySocketTCP/MySocketTCP.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetector/slsDetectorUsers.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsReceiver/slsReceiverFunctionList.cpp slsReceiver/slsReceiver_funcs.cpp slsReceiver/slsReceiverUsers.cpp + +OBJS = $(SRC_CLNT:.cpp=.o) + +HEADERS = $(SRC_CLNT:.cpp=.h) commonFiles/sls_detector_defs.h slsDetectorAnalysis/detectorData.h slsDetector/slsDetectorBase.h multiSlsDetector/multiSlsDetectorCommand.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h usersFunctions/angleFunction.h slsReceiverInterface/receiverInterface.h slsDetector/svnInfoLib.h slsReceiver/circularFifo.h slsReceiver/slsReceiver_funcs.h slsReceiver/svnInfoReceiverTmp.h slsReceiver/receiver_defs.h slsReceiver/slsReceiverFunctionList.h slsReceiver/slsReceiverUsers.h slsReceiver/svnInfoReceiver.h + + + +DESTDIR ?= bin +DOCDIR ?= docs + + +all: package $(SRC_CLNT) + echo "compiling all" + +intdoc: $(SRC_H) $(SRC_CLNT) + doxygen doxy.config + +doc: $(DOCDIR)/pdf/slsDetectorUsersDocs.pdf + +$(DOCDIR)/pdf/slsDetectorUsersDocs.pdf: slsDetectorUsersDocs + cd slsDetectorUsersDocs/latex && make + $(shell test -d $(DOCDIR) || mkdir -p $(DOCDIR)) + $(shell test -d $(DOCDIR)/pdf || mkdir -p $(DOCDIR)/pdf) + cp slsDetectorUsersDocs/latex/refman.pdf $(DOCDIR)/pdf/slsDetectorUsersDocs.pdf + + +htmldoc: $(DOCDIR)/html/slsDetectorUsersDocs + +$(DOCDIR)/html/slsDetectorUsersDocs: slsDetectorUsersDocs + $(shell test -d $(DOCDIR) || mkdir -p $(DOCDIR)) + $(shell test -d $(DOCDIR)/html || mkdir -p $(DOCDIR)/html) + $(shell test -d $(DOCDIR)/html/slsDetectorUsersDocs && rm -r $(DOCDIR)/html/slsDetectorUsersDocs) + cp -r slsDetectorUsersDocs/html $(DOCDIR)/html/slsDetectorUsersDocs + +slsDetectorUsersDocs: slsDetectorUsers.doxy slsDetector/slsDetectorUsers.h slsDetector/slsDetectorUsers.cpp slsDetectorAnalysis/detectorData.h + doxygen slsDetectorUsers.doxy + + +mythenVirtualServer: $(SRC_MYTHEN_SVC) + cd mythenDetectorServer && make -f Makefile.virtual DESTDIR=$(DESTDIR) + +gotthardVirtualServer: $(SRC_MYTHEN_SVC) + cd gotthardDetectorServer && make -f Makefile.virtual DESTDIR=$(DESTDIR) + + + +%.o : %.cpp %.h Makefile + $(CXX) -Wall -o $@ -c $< $(INCLUDES) $(DFLAGS) $(FLAGS) -fPIC $(EPICSFLAGS) -L/usr/lib64/ + +package: $(OBJS) $(DESTDIR)/libSlsDetector.so $(DESTDIR)/libSlsDetector.a + +$(DESTDIR)/libSlsDetector.so: $(OBJS) + $(CXX) -shared -Wl,-soname,libSlsDetector.so -o libSlsDetector.so $(OBJS) -lc $(INCLUDES) $(DFLAGS) $(FLAGS) $(EPICSFLAGS) -L/usr/lib64/ + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + mv libSlsDetector.so $(DESTDIR) + +$(DESTDIR)/libSlsDetector.a: $(OBJS) + ar rcs libSlsDetector.a $(OBJS) + mv libSlsDetector.a $(DESTDIR) + +clean: + rm -rf libSlsDetector.a libSlsDetector.so core docs/* slsDetectorUsersDocs $(OBJS) + + +#------------------------------------------------------------------------------- + +install: package + +install_inc: + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + cp -P slsDetector/slsDetectorUsers.h slsDetectorAnalysis/detectorData.h $(DESTDIR) slsReceiver/slsReceiverUsers.h + + diff --git a/slsDetectorSoftware/README b/slsDetectorSoftware/README new file mode 100644 index 000000000..2cbe78380 --- /dev/null +++ b/slsDetectorSoftware/README @@ -0,0 +1,21 @@ +This subversion repository contains + +Common directories +Please inform Anna, Beat and Ian if you make modifications to these directories +- MySocketTCP : socket class +- commonFiles : header file common to server and client +- slsDetector : base class with all main detector functionalities (client side) + + +Mythen specific directories +Please inform Anna if you make modifications to these directories +- mythenDetector : mythen specific funcs (mainly files I/O and angular conversion) +- mythenDetectorServer : mythen server (for etrax compiler) +- firmware lib might be added in the future + +Eiger specific directories +Please inform Beat and Ian if you make modifications to these directories +- eigerDetector : eiger specific funcs (mainly files I/O and ..) +- eigerDetectorServer : eiger server + +make doc diff --git a/slsDetectorSoftware/commonFiles/communication_funcs.c b/slsDetectorSoftware/commonFiles/communication_funcs.c new file mode 100755 index 000000000..a42371570 --- /dev/null +++ b/slsDetectorSoftware/commonFiles/communication_funcs.c @@ -0,0 +1,674 @@ + + +#include "communication_funcs.h" +//#include +#include /* for TCP_NODELAY */ +#include +#include +#include +#include + +#include +char lastClientIP[INET_ADDRSTRLEN]; +char thisClientIP[INET_ADDRSTRLEN]; +int lockStatus; +int differentClients; + +//int socketDescriptor, file_des; +const int send_rec_max_size=SEND_REC_MAX_SIZE; +extern int errno; + + +char dummyClientIP[INET_ADDRSTRLEN]; + + +fd_set readset, tempset; +int isock=0, maxfd; + + +int myport=-1; + +//struct sockaddr_in address; +//#define VERBOSE + + +int bindSocket(unsigned short int port_number) { + int i; + + struct sockaddr_in addressS; + int socketDescriptor; + //int file_des; + + //file_des= -1; + + + + + + + + + + + if (myport==port_number) + return -10; + + + + + + socketDescriptor = socket(AF_INET, SOCK_STREAM,0); //tcp + + //socketDescriptor = socket(PF_INET, SOCK_STREAM, 0); + + + + if (socketDescriptor < 0) { + printf("Can not create socket\n"); + } else { + + i = 1; + setsockopt(socketDescriptor, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); + // setsockopt(socketDescriptor, IPPROTO_TCP, TCP_NODELAY, (char *) &i, sizeof(i)); + // TCP_CORK + + // Set some fields in the serverAddress structure. + addressS.sin_family = AF_INET; + addressS.sin_addr.s_addr = htonl(INADDR_ANY); + addressS.sin_port = htons(port_number); + + // memset(&address.sin_addr, 0, sizeof(address.sin_addr)); + + + if(bind(socketDescriptor,(struct sockaddr *) &addressS,sizeof(addressS))<0){ + + printf("Can not create socket\n"); + + socketDescriptor=-1; + } else { + if (listen(socketDescriptor, 5)==0) { + + if (isock==0) { + FD_ZERO(&readset); + } + + + FD_SET(socketDescriptor, &readset); + isock++; + maxfd = socketDescriptor; + printf ("%d port %d fd %d\n",isock, port_number,socketDescriptor); + myport=port_number; + } else + printf("error on listen"); + } + } + + + + //int getrlimit(int resource, struct rlimit *rlim); + + + + return socketDescriptor; + +} + + + + + +int getServerError(int socketDescriptor) +{ + if (socketDescriptor<0) return 1; + else return 0; +}; + + +int acceptConnection(int socketDescriptor) { + + + int j; + + + struct sockaddr_in addressC; + int file_des=-1; + struct timeval tv; + int result; + + + //socklen_t address_length; + size_t address_length=sizeof(struct sockaddr_in); + + if (socketDescriptor<0) + return -1; + + memcpy(&tempset, &readset, sizeof(tempset)); + tv.tv_sec = 10000000; + tv.tv_usec = 0; + result = select(maxfd + 1, &tempset, NULL, NULL, &tv); + + if (result == 0) { + printf("select() timed out!\n"); + } else if (result < 0 && errno != EINTR) { + printf("Error in select(): %s\n", strerror(errno)); + } else if (result > 0) { +#ifdef VERBOSE + printf("select returned!\n"); +#endif + for (j=0; j=0) + close(file_des); + FD_CLR(file_des, &readset); +} + +void exitServer(int socketDescriptor) { + if (socketDescriptor>=0) + close(socketDescriptor); +#ifdef VERY_VERBOSE + printf("Closing server\n"); +#endif + FD_CLR(socketDescriptor, &readset); + socketDescriptor=-1; + isock--; +} + + + + +void swapData(void* val,int length,intType itype){ + int i; + int16_t* c= (int16_t*)val; + int32_t* a= (int32_t*)val; + int64_t* b= (int64_t*)val; + for(i=0; length > 0; i++){ + switch(itype){ + case INT16: + c[i] = ((c[i] & 0x00FF) << 8) | ((c[i] & 0xFF00) >> 8); + length -= sizeof(int16_t); + break; + case INT32: + a[i]=((a[i] << 8) & 0xFF00FF00) | ((a[i] >> 8) & 0xFF00FF ); + a[i]=(a[i] << 16) | ((a[i] >> 16) & 0xFFFF); + length -= sizeof(int32_t); + break; + case INT64: + b[i] = ((b[i] << 8) & 0xFF00FF00FF00FF00ULL ) | ((b[i] >> 8) & 0x00FF00FF00FF00FFULL ); + b[i] = ((b[i] << 16) & 0xFFFF0000FFFF0000ULL ) | ((b[i] >> 16) & 0x0000FFFF0000FFFFULL ); + b[i] = (b[i] << 32) | ((b[i] >> 32) & 0xFFFFFFFFULL); + length -= sizeof(int64_t); + break; + default: + length = 0; + break; + } + } +} + +int sendData(int file_des, void* buf,int length, intType itype){ +#ifndef PCCOMPILE +#ifdef EIGERD + swapData(buf, length, itype); +#endif +#endif + return sendDataOnly(file_des, buf, length); +} + + +int receiveData(int file_des, void* buf,int length, intType itype){ + int ret = receiveDataOnly(file_des, buf, length); +#ifndef PCCOMPILE +#ifdef EIGERD + swapData(buf, length, itype); +#endif +#endif + return ret; +} + + + int sendDataOnly(int file_des, void* buf,int length) { + + + return write(file_des, buf, length); +} + + + int receiveDataOnly(int file_des, void* buf,int length) { + + int total_received=0; + int nreceiving; + int nreceived; + if (file_des<0) return -1; +#ifdef VERY_VERBOSE + printf("want to receive %d Bytes\n", length); +#endif + + while(length>0){ + nreceiving = (length>send_rec_max_size) ? send_rec_max_size:length; + +#ifdef VERY_VERBOSE + printf("want to receive %d Bytes\n", nreceiving); +#endif + nreceived = read(file_des,(char*)buf+total_received,nreceiving); +#ifdef VERY_VERBOSE + printf("read %d \n", nreceived); +#endif + if(!nreceived) break; + // if(nreceived<0) break; + length-=nreceived; + total_received+=nreceived; + // cout<<"nrec: "<0) + strcpy(thisClientIP,dummyClientIP); + + //if (strcmp(lastClientIP,"none")==0) + //strcpy(lastClientIP,thisClientIP); + + if (strcmp(lastClientIP,thisClientIP)) + differentClients=1; + else + differentClients=0; + + return total_received; +} + + + + + + + + + + + + + + + +int sendChannel(int file_des, sls_detector_channel *myChan) { + int ts=0; + //sendDataOnly(file_des,myChan, sizeof(sls_detector_channel)); + ts+=sendData(file_des,&(myChan->chan),sizeof(myChan->chan),INT32); + ts+=sendData(file_des,&(myChan->chip),sizeof(myChan->chip),INT32); + ts+=sendData(file_des,&(myChan->module),sizeof(myChan->module),INT32); + ts+=sendData(file_des,&(myChan->reg),sizeof(myChan->reg),INT64); + return ts; +} + +int sendChip(int file_des, sls_detector_chip *myChip) { + int ts=0; + //ts+=sendDataOnly(file_des,myChip,sizeof(sls_detector_chip)); + ts+=sendData(file_des,&(myChip->chip),sizeof(myChip->chip),INT32); + ts+=sendData(file_des,&(myChip->module),sizeof(myChip->module),INT32); + ts+=sendData(file_des,&(myChip->nchan),sizeof(myChip->nchan),INT32); + ts+=sendData(file_des,&(myChip->reg),sizeof(myChip->reg),INT32); + ts+=sendData(file_des,(myChip->chanregs),sizeof(myChip->chanregs),INT32); + ts+=sendData(file_des,myChip->chanregs,myChip->nchan*sizeof(int),INT32); + return ts; +} + + +int sendModule(int file_des, sls_detector_module *myMod) { + return sendModuleGeneral(file_des, myMod, 1); +} + + +int sendModuleGeneral(int file_des, sls_detector_module *myMod, int sendAll) { + int ts=0; +#ifdef VERBOSE + int idac; +#endif + int nChips=myMod->nchip; + int nChans=myMod->nchan; + int nAdcs=myMod->nadc; + int nDacs=myMod->ndac; + //ts+= sendDataOnly(file_des,myMod,sizeof(sls_detector_module)); + ts+=sendData(file_des,&(myMod->module),sizeof(myMod->module),INT32); + ts+=sendData(file_des,&(myMod->serialnumber),sizeof(myMod->serialnumber),INT32); + ts+=sendData(file_des,&(myMod->nchan),sizeof(myMod->nchan),INT32); + ts+=sendData(file_des,&(myMod->nchip),sizeof(myMod->nchip),INT32); + ts+=sendData(file_des,&(myMod->ndac),sizeof(myMod->ndac),INT32); + ts+=sendData(file_des,&(myMod->nadc),sizeof(myMod->nadc),INT32); + ts+=sendData(file_des,&(myMod->reg),sizeof(myMod->reg),INT32); + ts+=sendData(file_des,myMod->dacs,sizeof(myMod->ndac),OTHER); + ts+=sendData(file_des,myMod->adcs,sizeof(myMod->nadc),OTHER); + /*some detectors dont require sending all trimbits etc.*/ + if(sendAll){ + ts+=sendData(file_des,myMod->chipregs,sizeof(myMod->nchip),OTHER); + ts+=sendData(file_des,myMod->chanregs,sizeof(myMod->nchan),OTHER); + } + ts+=sendData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); + ts+=sendData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + +#ifdef VERBOSE + printf("module %d of size %d sent\n",myMod->module, ts); +#endif + ts+= sendData(file_des,myMod->dacs,sizeof(dacs_t)*nDacs,INT32); +#ifdef VERBOSE + printf("dacs %d of size %d sent\n",myMod->module, ts); + for (idac=0; idac< nDacs; idac++) + printf("dac %d is %d\n",idac,(int)myMod->dacs[idac]); +#endif + ts+= sendData(file_des,myMod->adcs,sizeof(dacs_t)*nAdcs,INT32); +#ifdef VERBOSE + printf("adcs %d of size %d sent\n",myMod->module, ts); +#endif + + /*some detectors dont require sending all trimbits etc.*/ + if(sendAll){ + ts+=sendData(file_des,myMod->chipregs,sizeof(int)*nChips,INT32); +#ifdef VERBOSE + printf("chips %d of size %d sent\n",myMod->module, ts); +#endif + ts+=sendData(file_des,myMod->chanregs,sizeof(int)*nChans,INT32); +#ifdef VERBOSE + printf("chans %d of size %d sent - %d\n",myMod->module, ts, myMod->nchan); +#endif + } + +#ifdef VERBOSE + printf("module %d of size %d sent register %x\n",myMod->module, ts, myMod->reg); +#endif + return ts; +} + +int receiveChannel(int file_des, sls_detector_channel *myChan) { + int ts=0; + //receiveDataOnly(file_des,myChan,sizeof(sls_detector_channel)); + ts+=receiveData(file_des,&(myChan->chan),sizeof(myChan->chan),INT32); + ts+=receiveData(file_des,&(myChan->chip),sizeof(myChan->chip),INT32); + ts+=receiveData(file_des,&(myChan->module),sizeof(myChan->module),INT32); + ts+=receiveData(file_des,&(myChan->reg),sizeof(myChan->reg),INT32); + return ts; +} + +int receiveChip(int file_des, sls_detector_chip* myChip) { + + int *ptr=myChip->chanregs; + int ts=0; + int nChans, nchanold=myChip->nchan, chdiff; + + //ts+= receiveDataOnly(file_des,myChip,sizeof(sls_detector_chip)); + ts+=receiveData(file_des,&(myChip->chip),sizeof(myChip->chip),INT32); + ts+=receiveData(file_des,&(myChip->module),sizeof(myChip->module),INT32); + ts+=receiveData(file_des,&(myChip->nchan),sizeof(myChip->nchan),INT32); + ts+=receiveData(file_des,&(myChip->reg),sizeof(myChip->reg),INT32); + ts+=receiveData(file_des,(myChip->chanregs),sizeof(myChip->chanregs),INT32); + + myChip->chanregs=ptr; + nChans=myChip->nchan; + chdiff=nChans-nchanold; + if (nchanold!=nChans) { + printf("wrong number of channels received!\n"); + } + + +#ifdef VERBOSE + printf("chip structure received\n"); + printf("now receiving %d channels\n", nChans); +#endif + + if (chdiff<=0) + ts+=receiveData(file_des,myChip->chanregs, sizeof(int)*nChans,INT32); + else { + ptr=(int*)malloc(chdiff*sizeof(int)); + myChip->nchan=nchanold; + ts+=receiveData(file_des,myChip->chanregs, sizeof(int)*nchanold,INT32); + ts+=receiveData(file_des,ptr, sizeof(int)*chdiff,INT32); + free(ptr); + return FAIL; + } + +#ifdef VERBOSE + printf("chip's channels received\n"); +#endif + return ts; +} + + +int receiveModule(int file_des, sls_detector_module* myMod) { + return receiveModuleGeneral(file_des,myMod,1); +} + +int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveAll) { + int ts=0; + dacs_t *dacptr=myMod->dacs; + dacs_t *adcptr=myMod->adcs; + int *chipptr=myMod->chipregs, *chanptr=myMod->chanregs; + int nChips, nchipold=myMod->nchip, nchipdiff; + int nChans, nchanold=myMod->nchan, nchandiff; + int nDacs, ndold=myMod->ndac, ndacdiff; + int nAdcs, naold=myMod->nadc, nadcdiff; +#ifdef VERBOSE + int id=0; +#endif + // ts+= receiveDataOnly(file_des,myMod,sizeof(sls_detector_module)); + ts+=receiveData(file_des,&(myMod->module),sizeof(myMod->module),INT32); + ts+=receiveData(file_des,&(myMod->serialnumber),sizeof(myMod->serialnumber),INT32); + ts+=receiveData(file_des,&(myMod->nchan),sizeof(myMod->nchan),INT32); + ts+=receiveData(file_des,&(myMod->nchip),sizeof(myMod->nchip),INT32); + ts+=receiveData(file_des,&(myMod->ndac),sizeof(myMod->ndac),INT32); + ts+=receiveData(file_des,&(myMod->nadc),sizeof(myMod->nadc),INT32); + ts+=receiveData(file_des,&(myMod->reg),sizeof(myMod->reg),INT32); + ts+=receiveData(file_des,myMod->dacs,sizeof(myMod->ndac),INT32); + ts+=receiveData(file_des,myMod->adcs,sizeof(myMod->nadc),INT32); + /*some detectors dont require sending all trimbits etc.*/ + if(receiveAll){ + ts+=receiveData(file_des,myMod->chipregs,sizeof(myMod->nchip),INT32); + ts+=receiveData(file_des,myMod->chanregs,sizeof(myMod->nchan),INT32); + } + ts+=receiveData(file_des,&(myMod->gain), sizeof(myMod->gain),OTHER); + ts+=receiveData(file_des,&(myMod->offset), sizeof(myMod->offset),OTHER); + + myMod->dacs=dacptr; + myMod->adcs=adcptr; + myMod->chipregs=chipptr; + myMod->chanregs=chanptr; + + nChips=myMod->nchip; + nchipdiff=nChips-nchipold; + if (nchipold!=nChips) { + printf("received wrong number of chips\n"); + } +#ifdef VERBOSE + else + printf("received %d chips\n",nChips); +#endif + + nChans=myMod->nchan; + nchandiff=nChans-nchanold; + if (nchanold!=nChans) { + printf("received wrong number of channels\n"); + } +#ifdef VERBOSE + else + printf("received %d chans\n",nChans); +#endif + + + nDacs=myMod->ndac; + ndacdiff=nDacs-ndold; + if (ndold!=nDacs) { + printf("received wrong number of dacs\n"); + } +#ifdef VERBOSE + else + printf("received %d dacs\n",nDacs); +#endif + + nAdcs=myMod->nadc; + nadcdiff=nAdcs-naold; + if (naold!=nAdcs) { + printf("received wrong number of adcs\n"); + } +#ifdef VERBOSE + else + printf("received %d adcs\n",nAdcs); +#endif + if (ndacdiff<=0) { + ts+=receiveData(file_des,myMod->dacs, sizeof(dacs_t)*nDacs,INT32); +#ifdef VERBOSE + printf("dacs received\n"); + int id; + for (id=0; iddacs[id]); + + +#endif + } else { + dacptr=(dacs_t*)malloc(ndacdiff*sizeof(dacs_t)); + myMod->ndac=ndold; + ts+=receiveData(file_des,myMod->dacs, sizeof(dacs_t)*ndold,INT32); + ts+=receiveData(file_des,dacptr, sizeof(dacs_t)*ndacdiff,INT32); + free(dacptr); + return FAIL; + } + + if (nadcdiff<=0) { + ts+=receiveData(file_des,myMod->adcs, sizeof(dacs_t)*nAdcs,INT32); +#ifdef VERBOSE + printf("adcs received\n"); +#endif + } else { + adcptr=(dacs_t*)malloc(nadcdiff*sizeof(dacs_t)); + myMod->nadc=naold; + ts+=receiveData(file_des,myMod->adcs, sizeof(dacs_t)*naold,INT32); + ts+=receiveData(file_des,adcptr, sizeof(dacs_t)*nadcdiff,INT32); + free(adcptr); + return FAIL; + } + + + /*some detectors dont require sending all trimbits etc.*/ + if(receiveAll){ + + if (nchipdiff<=0) { + ts+=receiveData(file_des,myMod->chipregs, sizeof(int)*nChips,INT32); +#ifdef VERBOSE + printf("chips received\n"); +#endif + } else { + chipptr=(int*)malloc(nchipdiff*sizeof(int)); + myMod->nchip=nchipold; + ts+=receiveData(file_des,myMod->chipregs, sizeof(int)*nchipold,INT32); + ts+=receiveData(file_des,chipptr, sizeof(int)*nchipdiff,INT32); + free(chipptr); + return FAIL; + } + + if (nchandiff<=0) { + ts+=receiveData(file_des,myMod->chanregs, sizeof(int)*nChans,INT32); +#ifdef VERBOSE + printf("chans received\n"); +#endif + } else { + chanptr=(int*)malloc(nchandiff*sizeof(int)); + myMod->nchan=nchanold; + ts+=receiveData(file_des,myMod->chanregs, sizeof(int)*nchanold,INT32); + ts+=receiveData(file_des,chanptr, sizeof(int)*nchandiff,INT32); + free(chanptr); + return FAIL; + } + } +#ifdef VERBOSE + printf("received module %d of size %d register %x\n",myMod->module,ts,myMod->reg); +#endif + + return ts; +} diff --git a/slsDetectorSoftware/commonFiles/communication_funcs.h b/slsDetectorSoftware/commonFiles/communication_funcs.h new file mode 100755 index 000000000..e4e3fac27 --- /dev/null +++ b/slsDetectorSoftware/commonFiles/communication_funcs.h @@ -0,0 +1,51 @@ +#ifndef COMMUNICATION_FUNCS_H +#define COMMUNICATION_FUNCS_H + +#define SEND_REC_MAX_SIZE 4096 +#define DEFAULT_PORTNO 1952 +#include +#include + + +#include +#include +#include +#include + +#include "sls_detector_defs.h" + + + +typedef enum{ + INT16, + INT32, + INT64, + OTHER +}intType; + + + + +int bindSocket(unsigned short int port_number); +int acceptConnection(int socketDescriptor); +void closeConnection(int file_Des); +void exitServer(int socketDescriptor); + +void swapData(void* val,int length,intType itype); +int sendData(int file_des, void* buf,int length, intType itype); +int receiveData(int file_des, void* buf,int length, intType itype); +int sendDataOnly(int file_des, void* buf,int length); +int receiveDataOnly(int file_des, void* buf,int length); + + +int getServerError(int socketDescriptor); +int sendChannel(int file_des, sls_detector_channel *myChan); +int sendChip(int file_des, sls_detector_chip *myChip); +int sendModule(int file_des, sls_detector_module *myMod); +int sendModuleGeneral(int file_des, sls_detector_module *myMod, int sendAll); +int receiveChannel(int file_des, sls_detector_channel *myChan); +int receiveChip(int file_des, sls_detector_chip* myChip); +int receiveModule(int file_des, sls_detector_module* myMod); +int receiveModuleGeneral(int file_des, sls_detector_module* myMod, int receiveAll); + +#endif diff --git a/slsDetectorSoftware/commonFiles/error_defs.h b/slsDetectorSoftware/commonFiles/error_defs.h new file mode 100644 index 000000000..f1f6b58e0 --- /dev/null +++ b/slsDetectorSoftware/commonFiles/error_defs.h @@ -0,0 +1,261 @@ +/* + * error_defs.h + * + * Created on: Jan 18, 2013 + * Author: l_maliakal_d + */ + +#ifndef ERROR_DEFS_H_ +#define ERROR_DEFS_H_ + + +#include +#include +using namespace std; + + +#include "sls_detector_defs.h" + + + +/** Error flags */ +/*Assumption: Only upto 63 detectors */ +#define CRITICAL_ERROR_MASK 0xFFFFFFFF + +#define MULTI_DETECTORS_NOT_ADDED 0x8000000000000000ULL + + +#define CANNOT_CONNECT_TO_DETECTOR 0x8000000000000000ULL +#define CANNOT_CONNECT_TO_RECEIVER 0x4000000000000000ULL +#define COULDNOT_SET_CONTROL_PORT 0x2000000000000000ULL +#define COULDNOT_SET_STOP_PORT 0x1000000000000000ULL +#define COULDNOT_SET_DATA_PORT 0x0800000000000000ULL +#define FILE_PATH_DOES_NOT_EXIST 0x0400000000000000ULL +#define COULDNOT_CREATE_UDP_SOCKET 0x0200000000000000ULL +#define COULDNOT_CREATE_FILE 0x0100000000000000ULL +#define COULDNOT_ENABLE_COMPRESSION 0x0080000000000000ULL +#define RECEIVER_DET_HOSTNAME_NOT_SET 0x0040000000000000ULL +#define RECEIVER_DET_HOSTTYPE_NOT_SET 0x0020000000000000ULL +#define DETECTOR_TEN_GIGA 0x0010000000000000ULL +#define DETECTOR_ACTIVATE 0x0008000000000000ULL + +// 0xFFFFFFFF00000000ULL + +#define COULD_NOT_CONFIGURE_MAC 0x0000000000000001ULL +#define COULDNOT_SET_NETWORK_PARAMETER 0x0000000000000002ULL +#define COULDNOT_SET_ROI 0x0000000000000004ULL +#define RECEIVER_READ_FREQUENCY 0x0000000000000008ULL +#define SETTINGS_NOT_SET 0x0000000000000010ULL +#define SETTINGS_FILE_NOT_OPEN 0x0000000000000020ULL +#define COULDNOT_START_RECEIVER 0x0000000000000040ULL // default error like starting threads +#define COULDNOT_STOP_RECEIVER 0x0000000000000080ULL +#define DETECTOR_TIMER_VALUE_NOT_SET 0x0000000000000100ULL +#define RECEIVER_ACQ_PERIOD_NOT_SET 0x0000000000000200ULL +#define RECEIVER_FRAME_NUM_NOT_SET 0x0000000000000400ULL +#define RECEIVER_DYNAMIC_RANGE 0x0000000000000800ULL +#define RECEIVER_TEN_GIGA 0x0000000000001000ULL +#define ALLTIMBITS_NOT_SET 0x0000000000002000ULL +#define COULD_NOT_SET_SPEED_PARAMETERS 0x0000000000004000ULL +#define COULD_NOT_SET_READOUT_FLAGS 0x0000000000008000ULL +#define COULD_NOT_SET_FIFO_DEPTH 0x0000000000010000ULL +#define COULD_NOT_SET_COUNTER_BIT 0x0000000000020000ULL +#define COULD_NOT_PULSE_PIXEL 0x0000000000040000ULL +#define COULD_NOT_PULSE_PIXEL_NMOVE 0x0000000000080000ULL +#define COULD_NOT_PULSE_CHIP 0x0000000000100000ULL +#define COULD_NOT_SET_RATE_CORRECTION 0x0000000000200000ULL +#define DETECTOR_NETWORK_PARAMETER 0x0000000000400000ULL +#define RATE_CORRECTION_NOT_32BIT 0x0000000000800000ULL +#define RATE_CORRECTION_NO_TAU_PROVIDED 0x0000000001000000ULL +#define RECEIVER_ACTIVATE 0x0000000002000000ULL + +// 0x00000000FFFFFFFFULL +/** @short class returning all error messages for error mask */ +class errorDefs { + + +public: + + /** Constructor */ + errorDefs():errorMask(0){ + strcpy(notAddedList,""); + }; + + /** Gets the error message + * param errorMask error mask + /returns error message from error mask + */ + static string getErrorMessage(int64_t slsErrorMask){ + + string retval = ""; + + if(slsErrorMask&CANNOT_CONNECT_TO_DETECTOR) + retval.append("Cannot connect to Detector\n"); + + if(slsErrorMask&CANNOT_CONNECT_TO_RECEIVER) + retval.append("Cannot connect to Receiver\n"); + + if(slsErrorMask&COULDNOT_SET_CONTROL_PORT) + retval.append("Could not set control port\n"); + + if(slsErrorMask&COULDNOT_SET_STOP_PORT) + retval.append("Could not set stop port\n"); + + if(slsErrorMask&COULDNOT_SET_DATA_PORT) + retval.append("Could not set receiver port\n"); + + if(slsErrorMask&FILE_PATH_DOES_NOT_EXIST) + retval.append("Path to Output Directory does not exist\n"); + + if(slsErrorMask&COULDNOT_CREATE_UDP_SOCKET) + retval.append("Could not create UDP socket to start receiver\n"); + + if(slsErrorMask&COULDNOT_CREATE_FILE) + retval.append("Could not create file to start receiver.\nCheck permissions of output directory or the overwrite flag\n"); + + if(slsErrorMask&COULDNOT_ENABLE_COMPRESSION) + retval.append("Could not enable/disable data compression in receiver.\nThread creation failed or recompile code with MYROOT1 flag.\n"); + + if(slsErrorMask&RECEIVER_DET_HOSTNAME_NOT_SET) + retval.append("Could not send the detector hostname to the receiver.\n"); + + if(slsErrorMask&RECEIVER_DET_HOSTTYPE_NOT_SET) + retval.append("Could not send the detector type to the receiver.\n"); + + if(slsErrorMask&DETECTOR_TEN_GIGA) + retval.append("Could not enable/disable 10GbE in the detector.\n"); + + if(slsErrorMask&DETECTOR_ACTIVATE) + retval.append("Could not activate/deactivate detector\n"); + + + + + + if(slsErrorMask&COULD_NOT_CONFIGURE_MAC) + retval.append("Could not configure mac\n"); + + if(slsErrorMask&COULDNOT_SET_NETWORK_PARAMETER) + retval.append("Could not set network parameter. Should be valid and in proper format\n"); + + if(slsErrorMask&COULDNOT_SET_ROI) + retval.append("Could not set the exact region of interest. Verify ROI set by detector.\n"); + + if(slsErrorMask&RECEIVER_READ_FREQUENCY) + retval.append("Could not set receiver read frequency.\n"); + + if(slsErrorMask&SETTINGS_NOT_SET) + retval.append("Could not set settings.\n"); + + if(slsErrorMask&SETTINGS_FILE_NOT_OPEN) + retval.append("Could not open settings file. Verify if it exists.\n"); + + if(slsErrorMask&COULDNOT_START_RECEIVER) + retval.append("Could not start receiver.\n"); + + if(slsErrorMask&COULDNOT_STOP_RECEIVER) + retval.append("Could not stop receiver.\n"); + + if(slsErrorMask&DETECTOR_TIMER_VALUE_NOT_SET) + retval.append("Could not set one of timer values in detector.\n"); + + if(slsErrorMask&RECEIVER_ACQ_PERIOD_NOT_SET) + retval.append("Could not set acquisition period in receiver.\n"); + + if(slsErrorMask&RECEIVER_FRAME_NUM_NOT_SET) + retval.append("Could not set frame number in receiver.\n"); + + if(slsErrorMask&RECEIVER_DYNAMIC_RANGE) + retval.append("Could not set dynamic range in receiver.\n"); + + if(slsErrorMask&RECEIVER_TEN_GIGA) + retval.append("Could not enable/disable 10GbE in the receiver.\n"); + + if(slsErrorMask&ALLTIMBITS_NOT_SET) + retval.append("Could not set all trimbits to value.\n"); + + if(slsErrorMask&COULD_NOT_SET_SPEED_PARAMETERS) + retval.append("Could not set the speed parameter value\n"); + + if(slsErrorMask&COULD_NOT_SET_READOUT_FLAGS) + retval.append("Could not set the readout flag\n"); + + if(slsErrorMask&COULD_NOT_SET_FIFO_DEPTH) + retval.append("Could not set receiver fifo depth\n"); + + if(slsErrorMask&COULD_NOT_SET_COUNTER_BIT) + retval.append("Could not set/reset counter bit\n"); + + if(slsErrorMask&COULD_NOT_PULSE_PIXEL) + retval.append("Could not pulse pixel\n"); + + if(slsErrorMask&COULD_NOT_PULSE_PIXEL_NMOVE) + retval.append("Could not pulse pixel and move\n"); + + if(slsErrorMask&COULD_NOT_PULSE_CHIP) + retval.append("Could not pulse chip\n"); + + if(slsErrorMask&COULD_NOT_SET_RATE_CORRECTION) + retval.append("Could not set rate correction\n"); + + if(slsErrorMask&DETECTOR_NETWORK_PARAMETER) + retval.append("Could not set/get detector network parameter\n"); + + if(slsErrorMask&RATE_CORRECTION_NOT_32BIT) + retval.append("Rate correction Deactivated, must be in 32 bit mode\n"); + + if(slsErrorMask&RATE_CORRECTION_NO_TAU_PROVIDED) + retval.append("Rate correction Deactivated. No default tau provided in file\n"); + + if(slsErrorMask&RECEIVER_ACTIVATE) + retval.append("Could not activate/deactivate receiver\n"); + + + + //------------------------------------------------------ length of message + + + return retval; + + } + + + /** Sets multi error mask + @param multi error mask to be set to + /returns multi error mask + */ + int64_t setErrorMask(int64_t i){errorMask=i;return getErrorMask();}; + + /**returns multi error mask */ + int64_t getErrorMask(){return errorMask;}; + + /** Clears error mask + /returns error mask + */ + int64_t clearErrorMask(){errorMask=0;return errorMask;}; + + /** Gets the not added detector list + /returns list + */ + char* getNotAddedList(){return notAddedList;}; + + /** Append the detector to not added detector list + * @param name append to the list + /returns list + */ + void appendNotAddedList(const char* name){strcat(notAddedList,name);strcat(notAddedList,"+");}; + + /** Clears not added detector list + /returns error mask + */ + void clearNotAddedList(){strcpy(notAddedList,"");}; + +protected: + + /** Error Mask */ + int64_t errorMask; + + /** Detectors Not added List */ + char notAddedList[MAX_STR_LENGTH]; +}; + +#endif /* ERROR_DEFS_H_ */ diff --git a/slsDetectorSoftware/commonFiles/sls_detector_defs.h b/slsDetectorSoftware/commonFiles/sls_detector_defs.h new file mode 100755 index 000000000..ddc7d62c6 --- /dev/null +++ b/slsDetectorSoftware/commonFiles/sls_detector_defs.h @@ -0,0 +1,571 @@ +#ifndef SLS_DETECTOR_DEFS_H +#define SLS_DETECTOR_DEFS_H + + +#ifdef __CINT__ +#define MYROOT +#define __cplusplus +#endif + +//#include +#include "sls_receiver_defs.h" + +/** default maximum string length */ +#define MAX_SCAN_STEPS 2000 +/** maxmimum number of modules per controller*/ +#define MAXMODS 24 +/** maxmimum number of detectors ina multidetector structure*/ +#define MAXDET 100 +/** header length for data :gotthard*/ +#define HEADERLENGTH 12 + +#define DEFAULT_SUBFRAME_EXPOSURE_VAL 2621440 /** default value for sub frame value 2.6ms*/ +#define MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS 0x1FFFFFFF /** 29 bit register for max subframe exposure value */ + +/** maximum rois */ +#define MAX_ROIS 100 + + +typedef char mystring[MAX_STR_LENGTH]; +typedef double mysteps[MAX_SCAN_STEPS]; + + + +#ifndef DACS_FLOAT +typedef int dacs_t; +#else +typedef float dacs_t; +#endif + +#define DEFAULT_DET_MAC "00:aa:bb:cc:dd:ee" +#define DEFAULT_DET_IP "129.129.202.46" + + +/** + \file sls_detector_defs.h +This file contains all the basic definitions common to the slsDetector class +and to the server programs running on the detector + + + * @author Anna Bergamaschi + * @version 0.1alpha (any string) + * @see slsDetector + +$Revision: 824 $ + +*/ + + +/** get flag form most functions */ +#define GET_FLAG -1 + + +#ifdef __cplusplus + +/** @short class containing all the structures, constants and enum definitions */ +class slsDetectorDefs: public virtual slsReceiverDefs{ + public: + + slsDetectorDefs(){}; + +#endif + + + enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, enCalLog, angCalLog, MAX_ACTIONS}; + + + +/** + @short structure for a detector channel + + should not be used by unexperienced users + + \see ::channelRegisterBit +*/ + typedef struct { + int chan; /**< is the channel number */ + int chip; /**< is the chip number */ + int module; /**< is the module number */ + int64_t reg; /**< is the is the channel register (e.g. trimbits, calibration enable, comparator enable...) */ + } sls_detector_channel; + + /** + @short structure for a detector chip + + should not be used by unexperienced users + \see ::chipRegisterBit ::channelRegisterBit +*/ + typedef struct { + int chip; /**< is the chip number */ + int module; /**< is the module number */ + int nchan; /**< is the number of channels in the chip */ + int reg; /** +#include +#include +#include +#include + + + + +#include "xfs_types.h" +#include "xparameters.h" +#include "FebRegisterDefs.h" + +#include "Beb.h" + + + + struct BebInfo beb_infos[10]; + int bebInfoSize = 0; + + struct LocalLinkInterface ll_beb_local,* ll_beb; + + struct udp_header_type udp_header; + + int Beb_send_ndata; + unsigned int Beb_send_buffer_size; + unsigned int* Beb_send_data_raw; + unsigned int* Beb_send_data; + + int Beb_recv_ndata; + unsigned int Beb_recv_buffer_size; + unsigned int* Beb_recv_data_raw; + unsigned int* Beb_recv_data; + + short Beb_bit_mode; + int BEB_MMAP_SIZE = 0x1000; + + int Beb_activated = 1; + + + +void BebInfo_BebInfo(struct BebInfo* bebInfo, unsigned int beb_num){ + bebInfo->beb_number=beb_num; + bebInfo->serial_address=0; + strcpy(bebInfo->src_mac_1GbE,""); + strcpy(bebInfo->src_mac_10GbE,""); + strcpy(bebInfo->src_ip_1GbE,""); + strcpy(bebInfo->src_ip_10GbE,""); + bebInfo->src_port_1GbE=bebInfo->src_port_10GbE=0; +} + + +int BebInfo_SetSerialAddress(struct BebInfo* bebInfo, unsigned int a){ + //address pre shifted + if(a>0xff) return 0; + bebInfo->serial_address = 0x04000000 | ((a&0xff)<<16); + return 1; +} + + +int BebInfo_SetHeaderInfo(struct BebInfo* bebInfo, int ten_gig, char* src_mac, char* src_ip, unsigned int src_port){ + if(ten_gig){ strcpy(bebInfo->src_mac_10GbE,src_mac); strcpy(bebInfo->src_ip_10GbE,src_ip); bebInfo->src_port_10GbE = src_port;} + else { strcpy(bebInfo->src_mac_1GbE,src_mac); strcpy(bebInfo->src_ip_1GbE,src_ip); bebInfo->src_port_1GbE = src_port;} + return 1; +} + + + +unsigned int BebInfo_GetBebNumber(struct BebInfo* bebInfo) {return bebInfo->beb_number;} +unsigned int BebInfo_GetSerialAddress(struct BebInfo* bebInfo) {return bebInfo->serial_address;} +char* BebInfo_GetSrcMAC(struct BebInfo* bebInfo, int ten_gig) {return ten_gig ? bebInfo->src_mac_10GbE : bebInfo->src_mac_1GbE;} +char* BebInfo_GetSrcIP(struct BebInfo* bebInfo, int ten_gig) {return ten_gig ? bebInfo->src_ip_10GbE : bebInfo->src_ip_1GbE;} +unsigned int BebInfo_GetSrcPort(struct BebInfo* bebInfo, int ten_gig) {return ten_gig ? bebInfo->src_port_10GbE : bebInfo->src_port_1GbE;} + + +void BebInfo_Print(struct BebInfo* bebInfo){ + printf("\t%d) Beb Info.\n",bebInfo->beb_number); + printf("\t\tSerial Add: 0x%x\n",bebInfo->serial_address); + printf("\t\tMAC 1GbE: %s\n",bebInfo->src_mac_1GbE); + printf("\t\tIP 1GbE: %s\n",bebInfo->src_ip_1GbE); + printf("\t\tport 1GbE: %d\n",bebInfo->src_port_1GbE); + printf("\t\tMAC 10GbE: %s\n",bebInfo->src_mac_10GbE); + printf("\t\tIP 10GbE: %s\n",bebInfo->src_ip_10GbE); + printf("\t\tport 10GbE: %d\n",bebInfo->src_port_10GbE); +} + + +void Beb_Beb(){ + + Beb_send_ndata = 0; + Beb_send_buffer_size = 1026; + Beb_send_data_raw = malloc((Beb_send_buffer_size+1) * sizeof(unsigned int)); + Beb_send_data = &Beb_send_data_raw[1]; + + Beb_recv_ndata = 0; + Beb_recv_buffer_size = 1026; + Beb_recv_data_raw = malloc((Beb_recv_buffer_size+1) * sizeof(unsigned int)); + Beb_recv_data = &Beb_recv_data_raw[1]; + + udp_header= (struct udp_header_type){ + {0x00, 0x50, 0xc5, 0xb2, 0xcb, 0x46}, // DST MAC + {0x00, 0x50, 0xc2, 0x46, 0xd9, 0x02}, // SRC MAC + {0x08, 0x00}, + {0x45}, + {0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x40}, + {0x00}, + {0xff}, + {0x11}, + {0x00, 0x00}, + {129, 205, 205, 128}, // Src IP + {129, 205, 205, 122}, // Dst IP + {0x0f, 0xa1}, + {0x13, 0x89}, + {0x00, 0x00}, //{0x00, 0x11}, + {0x00, 0x00} + }; + + + if(!Beb_InitBebInfos()) exit(1); + + printf("Printing Beb infos:\n"); + unsigned int i; + for(i=1;i 0) + Beb_close(fd,csp0base); + + return ret; +} + +/* do not work at the moment */ +int Beb_SetSlaveViaSoftware(){ + + if(!Beb_activated) + return 0; + + //mapping new memory + u_int32_t* csp0base=0; + u_int32_t value = 0, ret = 1; + + //open file pointer + int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); + if(fd < 0) + cprintf(BG_RED,"Set Slave FAIL\n"); + else{ + value = Beb_Read32(csp0base, MASTERCONFIG_OFFSET); + value&=~MASTER_BIT; + value|=OVERWRITE_HARDWARE_BIT; + int newval = Beb_Write32(csp0base, MASTERCONFIG_OFFSET,value); + if(newval!=value) + cprintf(BG_RED,"Could not set Slave via Software\n"); + else + ret = 0; + } + + //close file pointer + if(fd > 0) + Beb_close(fd,csp0base); + + return ret; +} + +int Beb_Activate(int enable){ + //mapping new memory + u_int32_t* csp0base=0; + u_int32_t value = 0, ret = -1; + + //open file pointer + int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); + if(fd < 0) + cprintf(BG_RED,"Deactivate FAIL\n"); + else{ + if(enable > -1){ + value = Beb_Read32(csp0base, MASTERCONFIG_OFFSET); + printf("Deactivate register value before:%d\n",value); + if(enable) + value&=~DEACTIVATE_BIT; + else + value|=DEACTIVATE_BIT; + + int newval = Beb_Write32(csp0base, MASTERCONFIG_OFFSET,value); + if(newval!=value){ + if(enable) + cprintf(BG_RED,"Could not activate via Software\n"); + else + cprintf(BG_RED,"Could not deactivate via Software\n"); + } + } + + value = Beb_Read32(csp0base, MASTERCONFIG_OFFSET); + if(value&DEACTIVATE_BIT) ret = 0; + else ret = 1; + if(enable == -1){ + if(ret) + cprintf(BLUE,"Detector is active. Register value:%d\n", value); + else + cprintf(BG_RED,"Detector is deactivated! Register value:%d\n", value); + } + + } + //close file pointer + if(fd > 0) + Beb_close(fd,csp0base); + + Beb_activated = ret; + + return ret; +} + + +int Beb_SetNetworkParameter(enum detNetworkParameter mode, int val){ + + if(!Beb_activated) + return val; + + + //mapping new memory + u_int32_t* csp0base=0; + u_int32_t valueread = 0; + u_int32_t offset = TXM_DELAY_LEFT_OFFSET; + char modename[100] = ""; + + switch(mode){ + case TXN_LEFT: + offset = TXM_DELAY_LEFT_OFFSET; + strcpy(modename,"Transmission Delay Left"); + break; + case TXN_RIGHT: + offset = TXM_DELAY_RIGHT_OFFSET; + strcpy(modename,"Transmission Delay Right"); + break; + case TXN_FRAME: + offset = TXM_DELAY_FRAME_OFFSET; + strcpy(modename,"Transmission Delay Frame"); + break; + case FLOWCTRL_10G: + offset = TXM_FLOW_CONTROL_10G; + strcpy(modename,"Flow Control for 10G"); + if(val>0) val = 1; + break; + default: cprintf(BG_RED,"Unrecognized mode in network parameter: %d\n",mode); return -1; + } + //open file pointer + int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); + if(fd < 0){ + cprintf(BG_RED,"Could not read register to set network parameter. FAIL\n"); + return -1; + } + else{ + if(val > -1){ + valueread = Beb_Read32(csp0base, offset); + //cprintf(BLUE, "%s value before:%d\n",modename,valueread); + Beb_Write32(csp0base, offset,val); + cprintf(BLUE,"%s value:%d\n", modename,valueread); + } + + valueread = Beb_Read32(csp0base, offset); + //cprintf(BLUE,"%s value:%d\n", modename,valueread); + } + //close file pointer + if(fd > 0) + Beb_close(fd,csp0base); + + return valueread; +} + + +int Beb_ResetToHardwareSettings(){ + + if(!Beb_activated) + return 1; + + //mapping new memory + u_int32_t* csp0base=0; + u_int32_t value = 0, ret = 1; + + //open file pointer + int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); + if(fd < 0) + cprintf(BG_RED,"Reset to Hardware Settings FAIL\n"); + else{ + value = Beb_Write32(csp0base, MASTERCONFIG_OFFSET,0); + if(value) + cprintf(BG_RED,"Could not reset to hardware settings\n"); + else + ret = 0; + } + + //close file pointer + if(fd > 0) + Beb_close(fd,csp0base); + + return ret; +} + + + +u_int32_t Beb_GetFirmwareRevision(){ + //mapping new memory + u_int32_t* csp0base=0; + u_int32_t value = 0; + + //open file pointer + int fd = Beb_open(&csp0base,XPAR_VERSION); + if(fd < 0) + cprintf(BG_RED,"Firmware Revision Read FAIL\n"); + else{ + value = Beb_Read32(csp0base, FIRMWARE_VERSION_OFFSET); + if(!value) + cprintf(BG_RED,"Firmware Revision Number does not exist in this version\n"); + } + + //close file pointer + if(fd > 0) + Beb_close(fd,csp0base); + + return value; +} + + +u_int32_t Beb_GetFirmwareSoftwareAPIVersion(){ + //mapping new memory + u_int32_t* csp0base=0; + u_int32_t value = 0; + + //open file pointer + int fd = Beb_open(&csp0base,XPAR_VERSION); + if(fd < 0) + cprintf(BG_RED,"Firmware Software API Version Read FAIL\n"); + else{ + value = Beb_Read32(csp0base, FIRMWARESOFTWARE_API_OFFSET); + if(!value) + cprintf(BG_RED,"Firmware Software API Version does not exist in this version\n"); + } + + //close file pointer + if(fd > 0) + Beb_close(fd,csp0base); + + return value; +} + +void Beb_ResetFrameNumber(){ + + if(!Beb_activated) + return; + + //mapping new memory to read master top module configuration + u_int32_t* csp0base=0; + //open file pointer + int fd = Beb_open(&csp0base,XPAR_PLB_GPIO_SYS_BASEADDR); + if(fd < 0){ + cprintf(BG_RED,"Reset Frame Number FAIL\n"); + }else{ + //write a 1 + Beb_Write32(csp0base, FRAME_NUM_RESET_OFFSET, 1); + usleep(100000); //100ms + //write a 0 + Beb_Write32(csp0base, FRAME_NUM_RESET_OFFSET, 0); + printf("Frame Number Reset OK\n"); + //close file pointer + Beb_close(fd,csp0base); + } +} + + +void Beb_ClearBebInfos(){ + //unsigned int i; + //for(i=0;iSetSerialAddress(0); //0xc4000000 + b->SetHeaderInfo(0,"00:50:c2:46:d9:34","129.129.205.78",42000 + 26); // 1 GbE, ip address can be acquire from the network "arp" + b->SetHeaderInfo(1,"00:50:c2:46:d9:35","10.0.26.1",52000 + 26); //10 GbE, everything calculable/setable + beb_infos.push_back(b); + */ + + + return Beb_CheckSourceStuffBebInfo(); +} + + + +int Beb_SetBebSrcHeaderInfos(unsigned int beb_number, int ten_gig, char* src_mac, char* src_ip,unsigned int src_port){ + //so that the values can be reset externally for now.... + + unsigned int i = 1;/*Beb_GetBebInfoIndex(beb_number);*/ + /******* if(!i) return 0;****************************/ //i must be greater than 0, zero is the global send + BebInfo_SetHeaderInfo(&beb_infos[i],ten_gig,src_mac,src_ip,src_port); + + printf("Printing Beb info number (%d) :\n",i); + BebInfo_Print(&beb_infos[i]); + printf("\n"); + + return 1; +} + + + + +int Beb_CheckSourceStuffBebInfo(){ + unsigned int i; + for(i=1;i=bebInfoSize){ + printf("WriteTo index error.\n"); + return 0; + } + + Beb_send_data_raw[0] = 0x90000000 | BebInfo_GetSerialAddress(&beb_infos[index]); + if(Local_Write(ll_beb,4,Beb_send_data_raw)!=4) return 0; + + Beb_send_data_raw[0] = 0xc0000000; + if((Beb_send_ndata+1)*4!=Local_Write(ll_beb,(Beb_send_ndata+1)*4,Beb_send_data_raw)) return 0; + + return 1; +} + + +void Beb_SwapDataFun(int little_endian, unsigned int n, unsigned int *d){ + unsigned int i; + if(little_endian) for(i=0;i>8) | ((d[i]&0xff000000)>>24)); //little_endian + else for(i=0;i>16)); +} + + +int Beb_SetByteOrder(){ + return 1; +} + + +int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header_number, char* dst_mac, char* dst_ip, unsigned int dst_port){ + + if(!Beb_activated) + return 1; + + u_int32_t bram_phy_addr; + u_int32_t* csp0base=0; + /*u_int32_t* bram_ptr = NULL;*/ + if (ten_gig) + bram_phy_addr = 0xC6002000; + else + bram_phy_addr = 0xC6001000; + + if(!Beb_SetHeaderData(beb_number,ten_gig,dst_mac,dst_ip,dst_port)) return 0; + + + + int fd = Beb_open(&csp0base,bram_phy_addr); + if(fd < 0){ + cprintf(BG_RED,"Set up UDP Header FAIL\n"); + }else{ + //read data + memcpy(csp0base+header_number*16, &udp_header, sizeof(udp_header)); + //close file pointer + Beb_close(fd,csp0base); + } + return 1; +} + + +//int Beb_SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header_number, char* dst_mac, char* dst_ip, unsigned int dst_port){ +// unsigned int i = 1;/*Beb_GetBebInfoIndex(beb_number);*/ +// +// /***********************************if(!i) return 0; *************************************///i must be greater than 0, zero is the global send +// +// Beb_send_ndata = 14; +// Beb_send_data[0] = ten_gig ? 0x00020000 : 0x00010000; //write to fanout numbers 1 or 2 +// Beb_send_data[1] = ((header_number*8)<<16); +// if(!Beb_SetHeaderData(beb_number,ten_gig,dst_mac,dst_ip,dst_port)) return 0; +// +// Beb_SwapDataFun(1,12,&(Beb_send_data[2])); +// +// if(!Beb_WriteTo(i)) return 0; +// printf("beb dst_port:%d\n",dst_port); +// return 1; +//} + + +int Beb_SetHeaderData(unsigned int beb_number, int ten_gig, char* dst_mac, char* dst_ip, unsigned int dst_port){ + unsigned int i = 1;/*Beb_GetBebInfoIndex(beb_number);*/ + /***********************************if(!i) return 0; *************************************///i must be greater than 0, zero is the global send + return Beb_SetHeaderData1(BebInfo_GetSrcMAC(&beb_infos[i],ten_gig),BebInfo_GetSrcIP(&beb_infos[i],ten_gig),BebInfo_GetSrcPort(&beb_infos[i],ten_gig),dst_mac,dst_ip,dst_port); +} + +int Beb_SetHeaderData1(char* src_mac, char* src_ip, unsigned int src_port, char* dst_mac, char* dst_ip, unsigned int dst_port){ + /* example header*/ + //static unsigned int* word_ptr = new unsigned int [16]; + /*static*/ + /* + udp_header_type udp_header = { + {0x00, 0x50, 0xc5, 0xb2, 0xcb, 0x46}, // DST MAC + {0x00, 0x50, 0xc2, 0x46, 0xd9, 0x02}, // SRC MAC + {0x08, 0x00}, + {0x45}, + {0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x40}, + {0x00}, + {0xff}, + {0x11}, + {0x00, 0x00}, + {129, 205, 205, 128}, // Src IP + {129, 205, 205, 122}, // Dst IP + {0x0f, 0xa1}, + {0x13, 0x89}, + {0x00, 0x00}, //{0x00, 0x11}, + {0x00, 0x00} + }; +*/ + + if(!Beb_SetMAC(src_mac,&(udp_header.src_mac[0]))) return 0; + printf("Setting Source MAC to %s\n",src_mac); + if(!Beb_SetIP(src_ip,&(udp_header.src_ip[0]))) return 0; + printf("Setting Source IP to %s\n",src_ip); + if(!Beb_SetPortNumber(src_port,&(udp_header.src_port[0]))) return 0; + printf("Setting Source port to %d\n",src_port); + + if(!Beb_SetMAC(dst_mac,&(udp_header.dst_mac[0]))) return 0; + printf("Setting Destination MAC to %s\n",dst_mac); + if(!Beb_SetIP(dst_ip,&(udp_header.dst_ip[0]))) return 0; + printf("Setting Destination IP to %s\n",dst_ip); + if(!Beb_SetPortNumber(dst_port,&(udp_header.dst_port[0]))) return 0; + printf("Setting Destination port to %d\n",dst_port); + + + Beb_AdjustIPChecksum(&udp_header); + + unsigned int* base_ptr = (unsigned int *) &udp_header; + unsigned int num_words = ( sizeof(struct udp_header_type) + 3 ) / 4; + // for(unsigned int i=0; i %s\n",macVal); + return 0; + } + + int itemp; + sscanf(pch,"%x",&itemp); + dst_ptr[i] = (u_int8_t)itemp; + pch = strtok (NULL, ":"); + i++; + } + return 1; +} + +int Beb_SetIP(char* ip, uint8_t* dst_ptr){ + char ipVal[50];strcpy(ipVal,ip); + int i = 0; + char *pch = strtok (ipVal,"."); + while (pch != NULL){ + if(((i!=3) && ((strlen(pch)>3) || (strlen(pch)<1))) || ((i==3)&&((strlen(pch)<1) || (strlen(pch) > 3)))){ + printf("Error: in ip address -> %s\n",ipVal); + return 0; + } + + int itemp; + sscanf(pch,"%d",&itemp); + dst_ptr[i] = (u_int8_t)itemp; + pch = strtok (NULL, "."); + i++; + } + return 1; +} + +int Beb_SetPortNumber(unsigned int port_number, uint8_t* dst_ptr){ + dst_ptr[0] = (port_number >> 8) & 0xff ; + dst_ptr[1] = port_number & 0xff; + return 1; +} + + +void Beb_AdjustIPChecksum(struct udp_header_type *ip){ + unsigned char *cptr = (unsigned char *) ip->ver_headerlen; + + ip->ip_header_checksum[0] = 0; + ip->ip_header_checksum[1] = 0; + ip->total_length[0] = 0; + ip->total_length[1] = 28; // IP + UDP Header Length + + // calc ip checksum + unsigned int ip_checksum = 0; + unsigned int i; + for(i=0; i<10; i++){ + ip_checksum += ( (cptr[2*i] << 8) + (cptr[2*i + 1]) ); + if (ip_checksum & 0x00010000) ip_checksum = (ip_checksum + 1) & 0x0000ffff; + } + + ip->ip_header_checksum[0] = (ip_checksum >> 8) & 0xff ; + ip->ip_header_checksum[1] = ip_checksum & 0xff ; +} + + + +int Beb_SendMultiReadRequest(unsigned int beb_number, unsigned int left_right, int ten_gig, unsigned int dst_number, unsigned int npackets, unsigned int packet_size, int stop_read_when_fifo_empty){ + +// This is a dead function, will be removed in future +// ================================================== + + unsigned int i = 1;/*Beb_GetBebInfoIndex(beb_number); //zero is the global send*/ + + Beb_send_ndata = 3; + if(left_right == 1) Beb_send_data[0] = 0x00040000; + else if(left_right == 2) Beb_send_data[0] = 0x00080000; + else if(left_right == 3) Beb_send_data[0] = 0x000c0000; + else return 0; + + //packet_size/=2; + if(dst_number>0x3f) return 0; + if(packet_size>0x3ff) return 0; + if(npackets==0||npackets>0x100) return 0; + npackets--; + + + Beb_send_data[1] = 0x62000000 | (!stop_read_when_fifo_empty) << 27 | (ten_gig==1) << 24 | packet_size << 14 | dst_number << 8 | npackets; +#ifdef MARTIN + cprintf(GREEN, "Beb_send_data[1]:%X\n",Beb_send_data[1]); +#endif + Beb_send_data[2] = 0; + + Beb_SwapDataFun(0,2,&(Beb_send_data[1])); +#ifdef MARTIN + cprintf(GREEN, "Beb_send_data[1] Swapped:%X\n",Beb_send_data[1]); +#endif + + if(Beb_activated){ + if(!Beb_WriteTo(i)) return 0; + } + + return 1; +} + + +int Beb_SetUpTransferParameters(short the_bit_mode){ + if(the_bit_mode!=4&&the_bit_mode!=8&&the_bit_mode!=16&&the_bit_mode!=32) return 0; + Beb_bit_mode = the_bit_mode; + + //nimages = the_number_of_images; + // on_dst = 0; + + return 1; +} + + +int Beb_StopAcquisition() +{ + if(!Beb_activated) + return 1; + + u_int32_t* csp0base=0; + volatile u_int32_t valuel,valuer; + //open file pointer + int fd = Beb_open(&csp0base,XPAR_CMD_GENERATOR); + if(fd < 0){ + cprintf(BG_RED,"Beb Stop Acquisition FAIL\n"); + return 0; + }else{ + //find value + valuel = Beb_Read32(csp0base, (LEFT_OFFSET+STOP_ACQ_OFFSET)); + valuer = Beb_Read32(csp0base, (RIGHT_OFFSET+STOP_ACQ_OFFSET)); + //high + Beb_Write32(csp0base, (LEFT_OFFSET + STOP_ACQ_OFFSET),(valuel|STOP_ACQ_BIT)); + Beb_Write32(csp0base, (RIGHT_OFFSET + STOP_ACQ_OFFSET),(valuer|STOP_ACQ_BIT)); + //low + Beb_Write32(csp0base, (LEFT_OFFSET + STOP_ACQ_OFFSET),(valuel&(~STOP_ACQ_BIT))); + Beb_Write32(csp0base, (RIGHT_OFFSET + STOP_ACQ_OFFSET),(valuer&(~STOP_ACQ_BIT))); + + printf("Beb Stop Acquisition OK\n"); + //close file pointer + Beb_close(fd,csp0base); + } + return 1; +} + +int Beb_RequestNImages(unsigned int beb_number, int ten_gig, unsigned int dst_number, unsigned int nimages, int test_just_send_out_packets_no_wait){ + + if(!Beb_activated) + return 1; + + if(dst_number>64) return 0; + + unsigned int header_size = 4; //4*64 bits + unsigned int packet_size = ten_gig ? 0x200 : 0x80; // 4k or 1k packets + unsigned int npackets = ten_gig ? Beb_bit_mode*4 : Beb_bit_mode*16; + int in_two_requests = (!ten_gig&&Beb_bit_mode==32); + + // volatile u_int32_t* ptrl; + // volatile u_int32_t* ptrr; + u_int32_t send_header_command; + u_int32_t send_frame_command; + + if(in_two_requests) npackets/=2; + +#ifdef MARTIN + cprintf(RED, "----Beb_RequestNImages Start----\n"); + cprintf(RED, "beb_number:%X, ten_gig:%X,dst_number:%X,npackets:%X,Beb_bit_mode:%X,header_size:%X,nimages:%d,test_just_send_out_packets_no_wait:%X\n",beb_number,ten_gig,dst_number,npackets,Beb_bit_mode,header_size,nimages,test_just_send_out_packets_no_wait); +#endif + + // CMD_GEN core registers + // + // base for left feb fpga + 0x000 + // base for right feb fpga + 0x100 Bytes + // + // OFFSETs given in Bytes + // base+00 0xC0DE0001 (static r/o) + // base+04 0x636D6467 (static r/o, ASCII for "CMDG") + // + // base+08 1st 32bits of 1st command + // base+0c 2nd 32bits of 1st command + // + // base+10 1st 32bits of 2nd command + // base+14 2nd 32bits of 2nd command + // + // base+18 command counter (sends n commands) + // <32 Bit mode : 2 commands for 1 frame neccessary (header + frame) (10 frames = 20 commands) + // 32 Bit mode : 3 commands for 1 frame neccessary (header + 1st halfframe + 2nd halfframe) (10 frames = 30 commands) + // if > 0 core starts operation + // + // base+1c command mode (for 32 bit mode) + // 0 for 2 command mode (send 1st command and 2nd command) (header + frame) + // 1 on bit 31 for 3 command mode (send 1st command, 2nd command, and 2nd command) (header + 1st halfframe + 2nd halfframe) + // + // + // Warning: Hard coded base address 0xc5000000 (TBD) + // + + + u_int32_t right_port_value = 0x2000; + u_int32_t* csp0base=0; + volatile u_int32_t value; + //open file pointer + int fd = Beb_open(&csp0base,XPAR_CMD_GENERATOR); + if(fd < 0){ + cprintf(BG_RED,"Beb Request N Images FAIL\n"); + return 0; + }else{ + +#ifdef MARTIN + int i; + for (i=0; i < 10; i++) + printf("%X\n",Beb_Read32(baseaddr, (LEFT_OFFSET + i*4))); +#endif + // Generating commands + send_header_command = 0x62000000 | (!test_just_send_out_packets_no_wait) << 27 | (ten_gig==1) << 24 | header_size << 14 | 0; + send_frame_command = 0x62000000 | (!test_just_send_out_packets_no_wait) << 27 | (ten_gig==1) << 24 | packet_size << 14 | (npackets-1); + +#ifdef MARTIN + for (i=0; i < 10; i++) + printf("%X\n",Beb_Read32(baseaddr, (LEFT_OFFSET + i*4))); + printf("%d\n",in_two_requests); +#endif + + //"0x20 << 8" is dst_number (0x00 for left, 0x20 for right) + //Left + Beb_Write32(csp0base, (LEFT_OFFSET + FIRST_CMD_PART1_OFFSET),0); + Beb_Write32(csp0base, (LEFT_OFFSET + FIRST_CMD_PART2_OFFSET),send_header_command); + Beb_Write32(csp0base, (LEFT_OFFSET + SECOND_CMD_PART1_OFFSET),0); + Beb_Write32(csp0base, (LEFT_OFFSET + SECOND_CMD_PART2_OFFSET),send_frame_command); + value = Beb_Read32(csp0base,(LEFT_OFFSET + TWO_REQUESTS_OFFSET)); + if(in_two_requests) Beb_Write32(csp0base, (LEFT_OFFSET + TWO_REQUESTS_OFFSET),(value | TWO_REQUESTS_BIT)); + else Beb_Write32(csp0base, (LEFT_OFFSET + TWO_REQUESTS_OFFSET),(value &~(TWO_REQUESTS_BIT))); + + // Right + Beb_Write32(csp0base, (RIGHT_OFFSET + FIRST_CMD_PART1_OFFSET),0); + Beb_Write32(csp0base, (RIGHT_OFFSET + FIRST_CMD_PART2_OFFSET),send_header_command | right_port_value); + Beb_Write32(csp0base, (RIGHT_OFFSET + SECOND_CMD_PART1_OFFSET),0); + Beb_Write32(csp0base, (RIGHT_OFFSET + SECOND_CMD_PART2_OFFSET),send_frame_command | right_port_value); + value = Beb_Read32(csp0base,(RIGHT_OFFSET + TWO_REQUESTS_OFFSET)); + if(in_two_requests) Beb_Write32(csp0base, (RIGHT_OFFSET + TWO_REQUESTS_OFFSET),(value | TWO_REQUESTS_BIT)); + else Beb_Write32(csp0base, (RIGHT_OFFSET + TWO_REQUESTS_OFFSET),(value &~(TWO_REQUESTS_BIT))); + + + // Set number of frames + Beb_Write32(csp0base, (LEFT_OFFSET + COMMAND_COUNTER_OFFSET), nimages*(2+in_two_requests)); + Beb_Write32(csp0base, (RIGHT_OFFSET + COMMAND_COUNTER_OFFSET), nimages*(2+in_two_requests)); + +#ifdef MARTIN + for (i=0; i < 10; i++) + printf("%X\n",Beb_Read32(baseaddr, (LEFT_OFFSET + i*4))); //*(ptrl+i)); + printf("%d\n",in_two_requests); +#endif + + Beb_close(fd,csp0base); + +#ifdef MARTIN + printf("----Beb_RequestNImages----\n"); +#endif + } + + return 1; +} + + +int Beb_Test(unsigned int beb_number){ + printf("Testing module number: %d\n",beb_number); + + + //int SetUpUDPHeader(unsigned int beb_number, int ten_gig, unsigned int header_number, string dst_mac, string dst_ip, unsigned int dst_port){ + //SetUpUDPHeader(26,0,0,"60:fb:42:f4:e3:d2","129.129.205.186",22000); + + unsigned int index = Beb_GetBebInfoIndex(beb_number); + if(!index){ + printf("Error beb number (%d)not in list????\n",beb_number); + return 0; + } + + unsigned int i; + for(i=0;i<64;i++){ + if(!Beb_SetUpUDPHeader(beb_number,0,i,"60:fb:42:f4:e3:d2","129.129.205.186",22000+i)){ + printf("Error setting up header table....\n"); + return 0; + } + } + + // SendMultiReadRequest(unsigned int beb_number, unsigned int left_right, int ten_gig, unsigned int dst_number, unsigned int npackets, unsigned int packet_size, int stop_read_when_fifo_empty=1); + for(i=0;i<64;i++){ + if(!Beb_SendMultiReadRequest(beb_number,i%3+1,0,i,1,0,1)){ + printf("Error requesting data....\n"); + return 0; + } + } + + + return 1; +} + +// Returns the FPGA temperature from the xps sysmon ip core +// Temperature value is cropped and not well rounded +int Beb_GetBebFPGATemp() +{ + + u_int32_t* csp0base=0; + int temperature=0; + int ret; + //open file pointer + int fd = Beb_open(&csp0base,XPAR_SYSMON_0_BASEADDR); + if(fd < 0){ + cprintf(BG_RED,"Module Configuration FAIL\n"); + }else{ + //read data + ret = Beb_Read32(csp0base, FPGA_TEMP_OFFSET); + temperature = ((((float)(ret)/65536.0f)/0.00198421639f ) - 273.15f); // Static conversation, copied from xps sysmon standalone driver + //close file pointer + Beb_close(fd,csp0base); + } + + return temperature; +} + + + + + + +int Beb_open(u_int32_t** csp0base, u_int32_t offset){ + + int fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) + cprintf(BG_RED,"\nCan't find /dev/mem!\n"); + else{ +#ifdef VERBOSE + printf("/dev/mem opened\n"); +#endif + *csp0base = (u_int32_t*)mmap(0, BEB_MMAP_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, offset); + if (*csp0base == MAP_FAILED) { + cprintf(BG_RED,"\nCan't map memmory area!!\n"); + fd = -1; + } +#ifdef VERBOSE + else printf("CSP0 mapped %p\n",(void*)*csp0base); +#endif + } + return fd; +} + +u_int32_t Beb_Read32 (u_int32_t* baseaddr, u_int32_t offset){ + volatile u_int32_t value; + value=* (u_int32_t*)(baseaddr + offset/(sizeof(u_int32_t))); + return value; +} + + +u_int32_t Beb_Write32 (u_int32_t* baseaddr, u_int32_t offset, u_int32_t data){ + volatile u_int32_t *ptr1; + ptr1=(u_int32_t*)(baseaddr + offset/(sizeof(u_int32_t))); + *ptr1 = data; + return *ptr1; +} + +void Beb_close(int fd,u_int32_t* csp0base){ + if(fd >= 0) + close(fd); + munmap(csp0base,BEB_MMAP_SIZE); +} diff --git a/slsDetectorSoftware/eigerDetectorServer/Beb.cxx b/slsDetectorSoftware/eigerDetectorServer/Beb.cxx new file mode 100644 index 000000000..80746bbe6 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Beb.cxx @@ -0,0 +1,470 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + +//return reversed 1 means good, 0 means failed + + + +#include +#include +#include +#include +#include +#include +#include + + +#include "xfs_types.h" +#include "xparameters.h" + +#include "Beb.h" + +using namespace std; + +BebInfo::BebInfo(unsigned int beb_num){beb_number=beb_num;serial_address=0;src_mac_1GbE="";src_mac_10GbE="";src_ip_1GbE="";src_ip_10GbE=""; src_port_1GbE=src_port_10GbE=0;} +bool BebInfo::SetHeaderInfo(bool ten_gig, string src_mac, string src_ip, unsigned int src_port){ + if(ten_gig){ src_mac_10GbE = src_mac; src_ip_10GbE = src_ip; src_port_10GbE = src_port;} + else { src_mac_1GbE = src_mac; src_ip_1GbE = src_ip; src_port_1GbE = src_port;} + return 1; +} + +bool BebInfo::SetSerialAddress(unsigned int a){ + //address pre shifted + if(a>0xff) return 0; + serial_address = 0x04000000 | ((a&0xff)<<16); + return 1; +} + +void BebInfo::Print(){ + cout<<"\t"<Print(); + cout<InitNewMemory(XPAR_PLB_LL_NEW_MEMORY, arg1)) + printf("New Memory FAIL\n"); + else + printf("New Memory OK\n"); + +} + +Beb::~Beb(){ + delete ll; + delete [] send_data_raw; + delete [] recv_data_raw; +} + +void Beb::ClearBebInfos(){ + for(unsigned int i=0;iSetSerialAddress(0xff)) beb_infos.push_back(b0); //all bebs for reset and possibly get request data? + + if(!ReadSetUpFromFile("/home/root/executables/setup_beb.txt")) return 0; +/* + //loop through file to fill vector. + BebInfo* b = new BebInfo(26); + b->SetSerialAddress(0); //0xc4000000 + b->SetHeaderInfo(0,"00:50:c2:46:d9:34","129.129.205.78",42000 + 26); // 1 GbE, ip address can be acquire from the network "arp" + b->SetHeaderInfo(1,"00:50:c2:46:d9:35","10.0.26.1",52000 + 26); //10 GbE, everything calculable/setable + beb_infos.push_back(b); +*/ + + return CheckSourceStuffBebInfo(); +} + + + +bool Beb::SetBebSrcHeaderInfos(unsigned int beb_number, bool ten_gig, string src_mac, string src_ip,unsigned int src_port){ + //so that the values can be reset externally for now.... + + unsigned int i = GetBebInfoIndex(beb_number); + if(!i) return 0; //i must be greater than 0, zero is the global send + beb_infos[i]->SetHeaderInfo(ten_gig,src_mac,src_ip,src_port); + + cout<<"Printing Beb info number ("<Print(); + cout<>cmd_st; + if(!strcmp("add_beb",cmd_st)){ + if(!(iss>>value_i[0]>>value_i[1]>>str_mac1>>str_ip1>>str_mac10>>str_ip10)){ + cout<<"Error adding beb from "<SetSerialAddress(value_i[1]); + b->SetHeaderInfo(0,str_mac1,str_ip1,42000+value_i[0]); + b->SetHeaderInfo(1,str_mac10,str_ip10,52000+value_i[0]); + beb_infos.push_back(b); + } + } + + infile.close(); + + return 1; +} + + + +bool Beb::CheckSourceStuffBebInfo(){ + for(unsigned int i=1;iGetBebNumber(),0,"00:00:00:00:00:00","10.0.0.1",20000)||!SetHeaderData(beb_infos[i]->GetBebNumber(),1,"00:00:00:00:00:00","10.0.0.1",20000)){ + cout<<"Error in BebInfo for module number "<GetBebNumber()<<"."<Print(); + return 0; + } + } + return 1; +} + +unsigned int Beb::GetBebInfoIndex(unsigned int beb_numb){ + if(!beb_numb) return 0; + + for(unsigned int i=1;iGetBebNumber()) return i; + return 0; +} + + + +bool Beb::WriteTo(unsigned int index){ + if(index>=beb_infos.size()){ + cout<<"WriteTo index error."<GetSerialAddress(); + if(ll->Write(4,send_data_raw)!=4) return 0; + + send_data_raw[0] = 0xc0000000; + if((send_ndata+1)*4!=ll->Write((send_ndata+1)*4,send_data_raw)) return 0; + + return 1; +} + + +void Beb::SwapDataFun(bool little_endian, unsigned int n, unsigned int *d){ + if(little_endian) for(unsigned int i=0;i>8) | ((d[i]&0xff000000)>>24)); //little_endian + else for(unsigned int i=0;i>16)); +} + + +bool Beb::SetByteOrder(){ + send_data_raw[0] = 0x8fff0000; + if(ll->Write(4,send_data_raw)!=4) return 0; + + while((ll->Read(recv_buffer_size*4,recv_data_raw)/4)>0) cout<<"\t) Cleanning buffer ..."<GetSrcMAC(ten_gig),beb_infos[i]->GetSrcIP(ten_gig),beb_infos[i]->GetSrcPort(ten_gig),dst_mac,dst_ip,dst_port); +} + +bool Beb::SetHeaderData(string src_mac, string src_ip, unsigned int src_port, string dst_mac, string dst_ip, unsigned int dst_port){ + /* example header*/ + //static unsigned int* word_ptr = new unsigned int [16]; + static udp_header_type udp_header = { + {0x00, 0x50, 0xc5, 0xb2, 0xcb, 0x46}, // DST MAC + {0x00, 0x50, 0xc2, 0x46, 0xd9, 0x02}, // SRC MAC + {0x08, 0x00}, + {0x45}, + {0x00}, + {0x00, 0x00}, + {0x00, 0x00}, + {0x40}, + {0x00}, + {0xff}, + {0x11}, + {0x00, 0x00}, + {129, 205, 205, 128}, // Src IP + {129, 205, 205, 122}, // Dst IP + {0x0f, 0xa1}, + {0x13, 0x89}, + {0x00, 0x00}, //{0x00, 0x11}, + {0x00, 0x00} + }; + + if(!SetMAC(src_mac,&(udp_header.src_mac[0]))) return 0; + if(!SetIP(src_ip,&(udp_header.src_ip[0]))) return 0; + if(!SetPortNumber(src_port,&(udp_header.src_port[0]))) return 0; + + if(!SetMAC(dst_mac,&(udp_header.dst_mac[0]))) return 0; + if(!SetIP(dst_ip,&(udp_header.dst_ip[0]))) return 0; + if(!SetPortNumber(dst_port,&(udp_header.dst_port[0]))) return 0; + + + AdjustIPChecksum(&udp_header); + + unsigned int* base_ptr = (unsigned int *) &udp_header; + unsigned int num_words = ( sizeof(udp_header_type) + 3 ) / 4; + // for(unsigned int i=0; i "<3))||(i==3&&(ip.length()<1||ip.length()>3))){ + cout<<"Error: in ip address -> "<> 8) & 0xff ; + dst_ptr[1] = port_number & 0xff; + return 1; +} + + +void Beb::AdjustIPChecksum(udp_header_type *ip){ + unsigned char *cptr = (unsigned char *) ip->ver_headerlen; + + ip->ip_header_checksum[0] = 0; + ip->ip_header_checksum[1] = 0; + ip->total_length[0] = 0; + ip->total_length[1] = 28; // IP + UDP Header Length + + // calc ip checksum + unsigned int ip_checksum = 0; + for(unsigned int i=0; i<10; i++){ + ip_checksum += ( (cptr[2*i] << 8) + (cptr[2*i + 1]) ); + if (ip_checksum & 0x00010000) ip_checksum = (ip_checksum + 1) & 0x0000ffff; + } + + ip->ip_header_checksum[0] = (ip_checksum >> 8) & 0xff ; + ip->ip_header_checksum[1] = ip_checksum & 0xff ; +} + + + +bool Beb::SendMultiReadRequest(unsigned int beb_number, unsigned int left_right, bool ten_gig, unsigned int dst_number, unsigned int npackets, unsigned int packet_size, bool stop_read_when_fifo_empty){ + + unsigned int i = GetBebInfoIndex(beb_number); //zero is the global send + + send_ndata = 3; + if(left_right == 1) send_data[0] = 0x00040000; + else if(left_right == 2) send_data[0] = 0x00080000; + else if(left_right == 3) send_data[0] = 0x000c0000; + else return 0; + + //packet_size/=2; + if(dst_number>0x3f) return 0; + if(packet_size>0x3ff) return 0; + if(npackets==0||npackets>0x100) return 0; + npackets--; + + + send_data[1] = 0x62000000 | (!stop_read_when_fifo_empty) << 27 | (ten_gig==1) << 24 | packet_size << 14 | dst_number << 8 | npackets; + send_data[2] = 0; + + SwapDataFun(0,2,&(send_data[1])); + + if(!WriteTo(i)) return 0; + + return 1; +} + + +bool Beb::SetUpTransferParameters(short the_bit_mode){ + if(the_bit_mode!=4&&the_bit_mode!=8&&the_bit_mode!=16&&the_bit_mode!=32) return 0; + bit_mode = the_bit_mode; + + //nimages = the_number_of_images; + // on_dst = 0; + + return 1; +} + +bool Beb::RequestNImages(unsigned int beb_number, unsigned int left_right, bool ten_gig, unsigned int dst_number, unsigned int nimages, bool test_just_send_out_packets_no_wait){ + if(dst_number>64) return 0; + + unsigned int header_size = 4; //4*64 bits + unsigned int packet_size = ten_gig ? 0x200 : 0x80; // 4k or 1k packets + unsigned int npackets = ten_gig ? bit_mode*4 : bit_mode*16; + bool in_two_requests = (!ten_gig&&bit_mode==32); + if(in_two_requests) npackets/=2; + + //cout<<"here: "< +#include +#include +#include +#include // std::remove_if + +#include +#include +#include +#include +#include + +#include "Beb.h" +#include "slsDetectorServer_defs.h" //include port number + +using namespace std; + +enum cmd_string {evNotFound, + evRequestImages,evTestRequest, + evSetBitMode, + evSetupTableEntry,evSetDstParameters, + evTest,evTestSend, + evExitServer}; + +map enum_map; + +void init(){ + + enum_map["requestimages"] = evRequestImages; // + enum_map["testrequest"] = evTestRequest; // + + enum_map["setbitmode"] = evSetBitMode; // (resets on_dst and dst_requested) + + enum_map["setuptableentry"] = evSetupTableEntry; + enum_map["setdstparameters"] = evSetDstParameters; // (resets on_dst and dst_requested) + + enum_map["test"] = evTest; + enum_map["testsend"] = evTestSend; + enum_map["exitserver"] = evExitServer; + +} + +int server_list_s; +int server_conn_s; +int AccpetConnectionAndWaitForData(char* buffer, int maxlength); +bool WriteNClose(const char* buffer, int length); +bool SetupListenSocket(unsigned short int port); + + +string LowerCase(string str); +string GetNextString(string str,bool start_from_beginning=0); +void AddNumber(string& str, int n, int location=-1);//-1 means append + +int main(int argc, char* argv[]){ + cout<1) + bebs = new Beb(atoi(argv[1])); + else + bebs = new Beb(-1); + + // unsigned short int port_number = atoi(argv[1]); + + unsigned short int port_number = BEB_PORT; + if(!SetupListenSocket(port_number)) return 1; + + + int length=1000; + char data[1000]; + + int stop = 0; + time_t rawtime; + struct tm *timeinfo; + + bool send_to_ten_gig = 0; + int ndsts_in_use=32; + unsigned int nimages_per_request=1; + + int on_dst=0; + bool dst_requested[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + while(!stop){ + + cout< "<0){ + return_start_pos = return_message.length(); + + switch(enum_map.find(LowerCase(cmd))->second){ + + case evRequestImages : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); //dst number + if(tmp_str[0].length()<1||n[0]<0||n[0]>=ndsts_in_use){ + return_message.append("\tError executing: RequestImages (note dst_number must be less than ndsts_in_use that is set with SetDstParameters\n"); + ret_val = 1; + }else{ + dst_requested[n[0]] = 1; + ret_val=0; + tmp_str[1] = " ( "; + while(dst_requested[on_dst]){ + //waits on data + if((ret_val = (!bebs->RequestNImages(0,1,send_to_ten_gig,on_dst,nimages_per_request)||!bebs->RequestNImages(0,2,send_to_ten_gig,0x20|on_dst,nimages_per_request)))) break; + AddNumber(tmp_str[1],on_dst);tmp_str[1].append(" "); + dst_requested[on_dst++]=0; + on_dst%=ndsts_in_use; + } + if(ret_val) return_message.append("\tError executing: RequestImages "); + else{ return_message.append("\tExecuted: RequestImages "); AddNumber(return_message,n[0]);} + return_message.append(tmp_str[1]); + return_message.append(" )\n"); + } + break; + + case evTestRequest : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); //dst number + if(tmp_str[0].length()<1||n[0]<0||n[0]>=ndsts_in_use){ + return_message.append("\tError executing: TestRequest (note dst_number must be less than 2xndsts_in_use that is set with SetDstParameters\n"); + ret_val = 1; + }else{ + ret_val = (!bebs->RequestNImages(0,1,send_to_ten_gig,n[0],nimages_per_request,1)||!bebs->RequestNImages(0,2,send_to_ten_gig,0x20|n[0],nimages_per_request,1)); + if(ret_val) return_message.append("\tError executing: TestRequest \n"); + else{ return_message.append("\tExecuted: TestRequest "); AddNumber(return_message,n[0]); return_message.append("\n");} + } + break; + + case evSetBitMode : + on_dst = 0; + for(n[0]=0;n[0]<32;n[0]++) dst_requested[n[0]] = 0; //clear dst requested + n[0] = atoi(GetNextString(data).data()); + if((ret_val = !bebs->SetUpTransferParameters(n[0]))) return_message.append("\tError executing: SetBitMode \n"); + else{ return_message.append("\tExecuted: SetBitMode ");AddNumber(return_message,n[0]);return_message.append("\n");} + break; + + case evSetDstParameters : //move below // + on_dst = 0; + for(n[0]=0;n[0]<32;n[0]++) dst_requested[n[0]] = 0; //clear dst requested + n[0] = atoi(GetNextString(data).data()); //<1GbE(0) or 10GbE(1)> + n[1] = atoi(GetNextString(data).data()); // + n[2] = atoi(GetNextString(data).data()); // 0)> + + if((n[0]!=0&&n[0]!=1)||(n[1]<1||n[1]>32)||n[2]<1){ + return_message.append("\tError executing: SetDstParameters <1GbE(0) or 10GbE(1)> \n"); + ret_val=1; + } + else{ + send_to_ten_gig = n[0]; + ndsts_in_use=n[1]; + nimages_per_request=n[2]; + return_message.append("\tExecuted: SetDstParameters "); + AddNumber(return_message,n[0]);return_message.append(" "); + AddNumber(return_message,n[1]);return_message.append(" "); + AddNumber(return_message,n[2]);return_message.append(" "); + ret_val=0; + } + break; + + case evSetupTableEntry : + n[0] = atoi(GetNextString(data).data()); //beb_number; + n[1] = atoi(GetNextString(data).data()); //<1GbE(0) or 10GbE(1)> + n[2] = atoi(GetNextString(data).data()); //header_number + tmp_str[0] = GetNextString(data); //src_mac + tmp_str[1] = GetNextString(data); //src_ip + n[3] = atoi(GetNextString(data).data()); //src_port + tmp_str[2] = GetNextString(data); //dst_mac + tmp_str[3] = GetNextString(data); //dst_ip + n[4] = atoi((tmp_str[4]=GetNextString(data)).data()); //dst_port + + if(n[0]<1||(n[1]!=0&&n[1]!=1)||(n[2]<0||n[2]>63)||tmp_str[0].length()<1||tmp_str[1].length()<1||n[3]<0||tmp_str[2].length()<1||tmp_str[3].length()<1||n[4]<0||tmp_str[4].length()<1){ + return_message.append("\tError executing: SetupTableEntry <1GbE(0) or 10GbE(1)> \n"); + ret_val = 1; + }else{ + for(int i=0;i<32;i++)/** modified for Aldo*/ + ret_val = !bebs->SetBebSrcHeaderInfos(n[0],n[1],tmp_str[0],tmp_str[1],n[3])||!bebs->SetUpUDPHeader(n[0],n[1],n[2]+i,tmp_str[2],tmp_str[3],n[4]); + + if(ret_val) return_message.append("\tError Executing: SetupTableEntry "); + else return_message.append("\tExecuted: SetupTableEntry "); + AddNumber(return_message,n[0]);return_message.append(" "); + AddNumber(return_message,n[1]);return_message.append(" "); + AddNumber(return_message,n[2]);return_message.append(" "); + return_message.append(tmp_str[0]);return_message.append(" "); + return_message.append(tmp_str[1]);return_message.append(" "); + AddNumber(return_message,n[3]);return_message.append(" "); + return_message.append(tmp_str[2]);return_message.append(" "); + return_message.append(tmp_str[3]);return_message.append(" "); + AddNumber(return_message,n[4]); + } + break; + + case evTest : + n[0] = atoi(GetNextString(data).data()); + if(n[0]<1){ + return_message.append("\tError executing: Test \n"); + ret_val = 1; + }else{ + ret_val = !bebs->Test(n[0]); + if(ret_val) return_message.append("\tError Executing: Test "); + else return_message.append("\tExecuted: Test "); + AddNumber(return_message,n[0]); + } + break; + + + case evTestSend : + n[0] = atoi(GetNextString(data).data()); //beb_number; + n[1] = atoi(GetNextString(data).data()); //giga bit, ten giga bit + n[2] = atoi((tmp_str[0]=GetNextString(data)).data()); //header_number + + if(n[0]<1||(n[1]!=0&&n[1]!=1)||(n[2]<0||n[2]>63)||tmp_str[0].length()<1){ + return_message.append("\tError executing: TestSend <1GbE(0) or 10GbE(1)> \n"); + ret_val = 1; + }else{ + ret_val = !bebs->SendMultiReadRequest(n[0],1,n[1],n[2],1,0); + + if(ret_val) return_message.append("\tError Executing: TestSend "); + else return_message.append("\tExecuted: TestSend "); + AddNumber(return_message,n[0]);return_message.append(" "); + AddNumber(return_message,n[1]);return_message.append(" "); + AddNumber(return_message,n[2]);return_message.append(" "); + } + break; + + case evExitServer : + return_message.append("\tExiting Server ....\n"); + stop = 1; + ret_val = -200; + break; + + default : + return_message.append("\tWarning command \""); + return_message.append(cmd); + return_message.append("\" not found.\n"); + return_message.append("\t\tValid commands: "); + map::iterator it = enum_map.begin(); + while(it!=enum_map.end()){ + return_message.append((it++)->first); + return_message.append(" "); + } + + ret_val=-100; + break; + } + + return_message.append("\n"); + AddNumber(return_message,ret_val,return_start_pos); + if(ret_val!=0) break; + + cmd = GetNextString(data); + } + return_message.append("\n\n\n"); + + AddNumber(return_message,ret_val,0); + cout<0) return sub; + } + + return ""; +} + + + +void AddNumber(string& str, int n, int location){ + static char retval_st[100]; + sprintf(retval_st,"%d",n); + + if(location<0) str.append(retval_st); + else str.insert(location,retval_st); +} + + +bool SetupListenSocket(unsigned short int port){ + server_list_s=0; + server_conn_s=0; + + if((server_list_s = socket(AF_INET, SOCK_STREAM, 0))<0) return 0; + + struct sockaddr_in servaddr; /* socket address structure */ + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(port); + + if(bind(server_list_s,(struct sockaddr *) &servaddr,sizeof(servaddr))<0) return 0; + + if(listen(server_list_s,32) < 0){ // 1024 /* Backlog for listen() */ + return 0; + } + + return 1; +} + + +int AccpetConnectionAndWaitForData(char* buffer, int maxlength){ + if(server_list_s==0||maxlength<=0) return 0; + + if((server_conn_s = accept(server_list_s,NULL,NULL))< 0) return 0; + + int nread = read(server_conn_s,buffer,maxlength-1); + + if(nread<0) return 0; + + buffer[nread]='\0'; + return nread; +} + +bool WriteNClose(const char* buffer, int length){ + if(server_conn_s==0||length<=0) return 0; + + int nsent = write(server_conn_s,buffer,length); + if(close(server_conn_s)<0) return 0; + + server_conn_s=0; + return (nsent==length); +} + + + + diff --git a/slsDetectorSoftware/eigerDetectorServer/Commands.txt b/slsDetectorSoftware/eigerDetectorServer/Commands.txt new file mode 100644 index 000000000..e03e20865 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Commands.txt @@ -0,0 +1,28 @@ + +Internal setup: + setdac + trimbits + rate correction tau + high voltage + + +Setup: + photon energy + dynamic range (4,8,16,32) + number of images + exposure time + exposure period + readout speed(full speed, 1/2 speed, 1/4 or super slow) + readout mode (parallel, non-parallel or super safe) + trigger mode (internal,external start of series, external start of acquisitions, external window) + trigger polarity (pos/neg) + external gating (on, pos/neg) + + +Acquisition: + start acquisition + stop acquisition + acquisition in progress + wait until daq is finished + status (needs to be implemented) + diff --git a/slsDetectorSoftware/eigerDetectorServer/Eiger.cxx b/slsDetectorSoftware/eigerDetectorServer/Eiger.cxx new file mode 100644 index 000000000..43ac6c5fc --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Eiger.cxx @@ -0,0 +1,1027 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + +#include +#include +#include + +#include +#include +#include +#include + + +#include "EigerRegisterDefs.h" +#include "Eiger.h" + +using namespace std; + +//GetDAQStatusRegister(512,current_mode_bits_from_fpga)){ + +const unsigned int Module::ndacs = 16; +const string Module::dac_names[16] = {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"}; + + +Module::Module(unsigned int number, unsigned int address_top){ + module_number = number; + top_address_valid = 1; + top_left_address = 0x100 | (0xff & address_top); + top_right_address = 0x200 | (0xff & address_top); + bottom_address_valid = 0; + bottom_left_address = 0; + bottom_right_address = 0; + + high_voltage = -1; + top_dac = new float [ndacs]; + bottom_dac = new float [ndacs]; + for(unsigned int i=0;iGetModuleNumber()); + ReadSetUpFile(modules[i]->GetModuleNumber(),st); + } + + return CheckSetup(); +} + + +bool Eiger::ReadSetUpFileToAddModules(string file_name){ + static ifstream infile; + static string line; + static char cmd_st[2000]; + static int value_i[3]; + + infile.open(file_name.c_str(),ios::in); + if(!infile.is_open()) return 0; + + cout<>cmd_st; + if(!strcmp("add_module",cmd_st)){ + if(!(iss>>value_i[0]>>value_i[1]>>value_i[2])){ + cout<<"Error adding module from "<>value_i[0]>>value_i[1])){ + cout<<"Error adding half module from "<TopAddressIsValid()){ + feb_list[nfebs++] = modules[i]->GetTopRightAddress(); + feb_list[nfebs++] = modules[i]->GetTopLeftAddress(); + } + if(modules[i]->BottomAddressIsValid()){ + feb_list[nfebs++] = modules[i]->GetBottomRightAddress(); + feb_list[nfebs++] = modules[i]->GetBottomLeftAddress(); + } + } + + SendCompleteFebList(nfebs,feb_list); + delete [] feb_list; + + cout<GetModuleNumber()<<" "; + if(modules[i]->TopAddressIsValid()) cout<GetTopBaseAddress()<<" (top) "<BottomAddressIsValid()) cout<GetBottomBaseAddress()<<" (bottom)"<GetModuleNumber()==module_number){ + module_index=i; + return 1; + } + } + + return 0; +} + +bool Eiger::CheckModuleAddresses(unsigned int top_address, unsigned int bottom_address){ + bool found_t = 0; + bool found_b = 0; + for(unsigned int i=0;iGetTopBaseAddress() || top_address==modules[i]->GetBottomBaseAddress())) found_t=1; + if(bottom_address!=0 && (bottom_address==modules[i]->GetTopBaseAddress() || bottom_address==modules[i]->GetBottomBaseAddress())) found_b=1; + } + + if(top_address==bottom_address) cout<<"\tWarning: top and bottom address are the same "<>cmd_st; + + if(cmd_st[0]=='#'||!strcmp("add_module",cmd_st)||!strcmp("add_half_module",cmd_st)){ ;// cout<<"do nothing "<>value_i[0])) cout<<"Error reading iodelay from "<>value_f; + SetHighVoltage(module_num,value_f); + }else if(!strcmp("photon_energy",cmd_st)){ + iss>>value_f; + SetPhotonEnergy(value_f); + }else if(!strcmp("dynamic_range",cmd_st)){ + iss>>value_i[0]; + SetDynamicRange(value_i[0]); + }else if(!strcmp("readout_speed",cmd_st)){ + iss>>value_i[0]; + SetReadoutSpeed(value_i[0]); + }else if(!strcmp("readout_mode",cmd_st)){ + iss>>value_i[0]; + SetReadoutMode(value_i[0]); + }else{ + iss>>value_f; + if(module_num>0) sprintf(cmd_st,"mod%d::%s",module_num,cmd_st); + if(!SetDAC(cmd_st,value_f)) cout<<"error in string: "<GetTopIDelay(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s idelay top number "<GetBottomIDelay(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s idelay bottom number "<GetHighVoltage()<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s high voltage not set."<GetTopDACVoltage(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s top \""<GetBottomDACVoltage(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s bottom \""<TopAddressIsValid()) n_half_modules++; + if(modules[i]->BottomAddressIsValid()) n_half_modules++; + } + + return n_half_modules; +} + +bool Eiger::SetPhotonEnergy(unsigned int full_energy_eV){ + photon_energy_eV = full_energy_eV; + cout<<"Setting photon energy to: "<3){ + cout<<"Error SetIDelay chip_pos "<TopAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetTopLeftAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetTopIDelay(chip_pos,ndelay_units); + else for(unsigned int i=0;iSetTopIDelay(chip_pos,ndelay_units); + }else{ + cout<<"Error could not set idelay module number "<BottomAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetBottomLeftAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetBottomIDelay(chip_pos,ndelay_units); + else for(unsigned int i=0;iSetBottomIDelay(chip_pos,ndelay_units); + }else{ + cout<<"Error could not set idelay module number "<TopAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetTopRightAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetTopIDelay(chip_pos,ndelay_units); + else for(unsigned int i=0;iSetTopIDelay(chip_pos,ndelay_units); + }else{ + cout<<"Error could not set idelay module number "<BottomAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetBottomRightAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetBottomIDelay(chip_pos,ndelay_units); + else for(unsigned int i=0;iSetBottomIDelay(chip_pos,ndelay_units); + }else{ + cout<<"Error could not set idelay module number "<0x3ff) ndelay_units=0x3ff; + // this is global + unsigned int delay_data_valid_nclks = 15 - ((ndelay_units&0x3c0)>>6); //data valid delay upto 15 clks + ndelay_units &= 0x3f; //up to 64 delay units + // ndelay_unit |= 0x40; //and one bit for a full clock delay for the enabled pixels is zero for now + + unsigned int set_left_delay_channels = chip_lr ? channels:0; + unsigned int set_right_delay_channels = chip_lr ? 0:channels; + + cout<<"\tSetting delays of "; + if(set_left_delay_channels!=0) cout<<"left chips of dst_num "<vmax) return 0; + digital = int(((value-vmin)/(vmax-vmin))*(nsteps-1) + 0.5); + return 1; +} + +float Eiger::DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax){ + return vmin+(vmax-vmin)*digital/(nsteps-1); +} + + +bool Eiger::SetHighVoltage(unsigned int module_num,float value){ + unsigned int module_index=0; + if(!GetModuleIndex(module_num,module_index)||!modules[module_index]->TopAddressIsValid()){ + cout<<"Error could not set high voltage module number "<GetTopRightAddress(),value)) return 0; + + if(module_index!=0) modules[module_index]->SetHighVoltage(value); + else for(unsigned int i=0;iSetHighVoltage(value); + + cout<<"\tHigh voltage of dst "<GetTopRightAddress()<<" set to "<GetHighVoltage()<<"."<TopAddressIsValid()){ + float v = value; + if(!SendDACValue(modules[module_index]->GetTopRightAddress(),dac_ch,v)) return 0; + if(module_index!=0) modules[module_index]->SetTopDACVoltage(dac_ch,v); + else for(unsigned int i=0;iSetTopDACVoltage(dac_ch,v); + + } + if(bottom&&modules[module_index]->BottomAddressIsValid()){ + float v = value; + if(!SendDACValue(modules[module_index]->GetBottomRightAddress(),dac_ch,v)) return 0; + if(module_index!=0) modules[module_index]->SetBottomDACVoltage(dac_ch,v); + else for(unsigned int i=0;iSetBottomDACVoltage(dac_ch,v); + } + + return 1; +} + +bool Eiger::GetDAC(std::string s, float& ret_value){ + cout<<"Function Eiger::GetDAC need to be finished....."<=Module::ndacs){ + cout<<"Warning: Eiger::GetDACName index out of range, "<15){ + cout<<"Warning invalid ch for SetDAC."<>3)<<((7-i)*4);//upper + trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])<<((7-i)*4);//low + trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])>>3)<<((7-i)*4);//upper + } + } + } + + if(!WriteMemory(0,0,0,1024,trimbits_to_load_r)||!WriteMemory(1,0,0,1024,trimbits_to_load_l)||!StartDAQOnlyNWaitForFinish()) return 0; + } + } + + memcpy(last_downloaded_trimbits,trimbits,trimbit_size*sizeof(unsigned char)); + + return SetStaticBits(); //send the static bits +} + + +unsigned char* Eiger::GetTrimbits(){ + return last_downloaded_trimbits; +} + + + + +bool Eiger::SetCommandRegister(unsigned int cmd){ + // if(fifo_enabled){ + // return WriteRegister(-1,DAQ_REG_CHIP_CMDS,cmd | DAQ_FIFO_ENABLE); + // } + return WriteRegister(0xfff,DAQ_REG_CHIP_CMDS,cmd); +} + + +bool Eiger::GetDAQStatusRegister(int socket_num, unsigned int &ret_status){ + + if(!ReadRegister(socket_num,DAQ_REG_STATUS,ret_status)){ + cout<<"Error: reading status register."<> 16; + return 1; +} + + +bool Eiger::StartDAQOnlyNWaitForFinish(int sleep_time_us){ + if(!WriteRegister(0xfff,DAQ_REG_CTRL,0)||!WriteRegister(0xfff,DAQ_REG_CTRL,DAQ_CTRL_START)){ + cout<<"Warning: could not start."<full,1->half,2->quarter or 3->super_slow + acquireNReadoutMode &= (~DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED); + if(readout_speed==1){ + acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_HALF_SPEED; + cout<<"Everything at half speed, ie. reading with 50 MHz main clk (half speed) ...."<parallel,1->non-parallel,2-> safe_mode + acquireNReadoutMode &= (~DAQ_NEXPOSURERS_PARALLEL_MODE); + if(readout_mode==1){ + acquireNReadoutMode |= DAQ_NEXPOSURERS_NORMAL_NONPARALLEL_MODE; + cout<<"Readout mode set to normal non-parallel readout mode ... "< internal exposure time and period, + //"01"-> external acquistion start and internal exposure time and period, + //"10"-> external start trigger and internal exposure time, + //"11"-> external triggered start and stop of exposures + triggerMode = (~DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP); + + if(trigger_mode == 1){ + triggerMode = DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START; + cout<<"Trigger mode: external start of acquisition sequence, internal exposure length and period."<(pow(2,29)-1)*pow(10,7)){ + float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); + cout<<"Warning: time exceeds ("<pow(2,29)-1){ power_of_ten++; n_clk_cycles = round(n_clk_cycles/10.0);} + decoded_time = int(n_clk_cycles)<<3 | int(power_of_ten); + } + + return decoded_time; +} + + +bool Eiger::ResetDataStream(){ + //for(int i=0;i<10;i++) cout<<"Warning need to think about reseting data stream ...."< +#include + +#include "Feb.h" + + +class Module{ + + private: + unsigned int module_number; + bool top_address_valid; + unsigned int top_left_address; + unsigned int top_right_address; + bool bottom_address_valid; + unsigned int bottom_left_address; + unsigned int bottom_right_address; + + unsigned int idelay_top[4]; //ll,lr,rl,ll + unsigned int idelay_bottom[4]; //ll,lr,rl,ll + float high_voltage; + float* top_dac; + float* bottom_dac; + + public: + Module(unsigned int number, unsigned int address_top); //for half module() + Module(unsigned int number, unsigned int address_top, unsigned int address_bottom); + ~Module(); + + static const unsigned int ndacs; + static const std::string dac_names[16]; + + unsigned int GetModuleNumber() {return module_number;} + bool TopAddressIsValid() {return top_address_valid;} + unsigned int GetTopBaseAddress() {return (top_left_address&0xff);} + unsigned int GetTopLeftAddress() {return top_left_address;} + unsigned int GetTopRightAddress() {return top_right_address;} + unsigned int GetBottomBaseAddress() {return (bottom_left_address&0xff);} + bool BottomAddressIsValid() {return bottom_address_valid;} + unsigned int GetBottomLeftAddress() {return bottom_left_address;} + unsigned int GetBottomRightAddress() {return bottom_right_address;} + + unsigned int SetTopIDelay(unsigned int chip,unsigned int value) { return TopAddressIsValid() &&chip<4 ? (idelay_top[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr + unsigned int GetTopIDelay(unsigned int chip) { return chip<4 ? idelay_top[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr + unsigned int SetBottomIDelay(unsigned int chip,unsigned int value) { return BottomAddressIsValid() &&chip<4 ? (idelay_bottom[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr + unsigned int GetBottomIDelay(unsigned int chip) { return chip<4 ? idelay_bottom[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr + + float SetHighVoltage(float value) { return TopAddressIsValid() ? (high_voltage=value) : -1;} + float GetHighVoltage() { return high_voltage;} + + float SetTopDACVoltage(unsigned int i, float value) { return (i modules; + void ClearModules(); + + unsigned int staticBits; //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 + unsigned int acquireNReadoutMode; //safe or parallel, half or full speed + unsigned int triggerMode; //internal timer, external start, external window, signal polarity (external trigger and enable) + unsigned int externalEnableMode; //external enabling engaged and it's polarity + unsigned int subFrameMode; + + unsigned int photon_energy_eV; + + unsigned int nimages; + float exposure_time_in_sec; + float exposure_period_in_sec; + + unsigned int trimbit_size; + unsigned char* last_downloaded_trimbits; + + void PrintModuleList(); + bool GetModuleIndex(unsigned int module_number, unsigned int& module_index); + bool CheckModuleAddresses(unsigned int top_address, unsigned int bottom_address); + bool AddModule(unsigned int module_number, unsigned int top_address); + bool AddModule(unsigned int module_number, unsigned int top_address, unsigned int bottom_address, bool half_module=0); + + bool GetDACNumber(std::string s, unsigned int& n); + bool SendDACValue(unsigned int dst_num, unsigned int ch, float& value); + bool VoltageToDAC(float value, unsigned int& digital, unsigned int nsteps, float vmin, float vmax); + float DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax); + + bool SendHighVoltage(unsigned int module_index, float& value); + + bool SendIDelays(unsigned int dst_num, bool chip_lr, unsigned int channels, unsigned int ndelay_units); + + bool SetStaticBits(); + bool SetStaticBits(unsigned int the_static_bits); + + unsigned int ConvertTimeToRegister(float time_in_sec); + + bool SetCommandRegister(unsigned int cmd); + bool GetDAQStatusRegister(int socket_num, unsigned int &ret_status); + bool StartDAQOnlyNWaitForFinish(int sleep_time_us=5000); + bool ResetDataStream(); + + bool ResetChipCompletely(); + + public: + Eiger(); + virtual ~Eiger(); + + bool Init(); + bool ReadSetUpFileToAddModules(std::string file_name); + bool ReadSetUpFile(unsigned int module_num, std::string file_name); + bool CheckSetup(); + + unsigned int GetNModules(); + unsigned int GetNHalfModules(); + + //bool SetHighVoltage(float value); + bool SetHighVoltage(unsigned int module_num,float value); + + bool SetPhotonEnergy(unsigned int full_energy_eV); + unsigned int GetPhotonEnergy(){return photon_energy_eV;} + + bool SetIDelays(unsigned int module_num, unsigned int ndelay_units); + bool SetIDelays(unsigned int module_num, unsigned int chip_pos, unsigned int ndelay_units); + + bool SetDAC(std::string s, float value); + bool GetDAC(std::string s, float& ret_value); + bool GetDACName(unsigned int dac_num, std::string &s); + + bool SetTrimbits(unsigned char* trimbits); + unsigned char* GetTrimbits(); + + + + bool Reset(); + bool StartAcquisition(); + bool StopAcquisition(); + bool AcquisitionInProgress(); + bool WaitForFinishedFlag(int sleep_time_us=5000); + + //functions for setting up exposure + void PrintAcquisitionSetup(); + bool SetNImages(unsigned int n_images); + unsigned int GetNImages(); + bool SetExposureTime(float the_exposure_time_in_sec); + float GetExposureTime(); + bool SetExposurePeriod(float the_exposure_period_in_sec); + float GetExposurePeriod(); + bool SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); + unsigned int GetDynamicRange(); + bool SetReadoutSpeed(unsigned int readout_speed=0); //0->full,1->half,2->quarter or 3->super_slow + bool SetReadoutMode(unsigned int readout_mode=0); //0->parallel,1->non-parallel,2-> safe_mode + bool SetTriggerMode(unsigned int trigger_mode=0, bool polarity=1); + bool SetExternalEnableMode(bool use_external_enable=0, bool polarity=1); + + + //functions for testing + bool SetTestModeVariable(bool on=1); + bool GetTestModeVariable(); + + bool FebTest(){return Feb::Test();} + +}; + + +#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/EigerBackEndFunctions.c b/slsDetectorSoftware/eigerDetectorServer/EigerBackEndFunctions.c new file mode 100644 index 000000000..1378160f5 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/EigerBackEndFunctions.c @@ -0,0 +1,200 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + +#include +#include +#include +#include + + + +#include "slsDetectorServer_defs.h" //include port number + +struct sockaddr_in eiger_back_socket_addr; +int eiger_back_max_message_length = 1024; +char eiger_back_message[1024]; +int eiger_back_message_length = 0; +int eiger_back_ret_val=0; + + +int bit_mode=0; +int ten_giga=0; + +int EigerBackInit(){ + static int passed = 0; + + if(!passed){ + struct hostent *dst_host; + if((dst_host = gethostbyname("localhost")) == NULL){ //or look into getaddrinfo(3) + fprintf(stderr,"ERROR, no such host\n"); + return 0; + }else{ + //struct sockaddr_in eiger_back_socket_addr; + int port = BEB_PORT; + bzero((char *) &eiger_back_socket_addr, sizeof(eiger_back_socket_addr)); + eiger_back_socket_addr.sin_family = AF_INET; + bcopy((char *)dst_host->h_addr,(char *)&eiger_back_socket_addr.sin_addr.s_addr,dst_host->h_length); + eiger_back_socket_addr.sin_port = htons(port); + passed = 1; + } + } + + return passed; +} + + +int EigerBackSendCMD(){ + if(!EigerBackInit()||eiger_back_message_length<=0) return 0; + + int sockfd = socket(AF_INET,SOCK_STREAM,0); + if(sockfd<0){ + fprintf(stderr,"ERROR opening socket\n"); + return 0; + } + + if(connect(sockfd,(struct sockaddr *) &eiger_back_socket_addr,sizeof(eiger_back_socket_addr))<0){ + fprintf(stderr,"ERROR connecting\n"); + return 0; + } + + int n = write(sockfd,eiger_back_message,eiger_back_message_length); + int ret_length = read(sockfd,eiger_back_message,eiger_back_max_message_length); + + close(sockfd); + + if(n<0||ret_length<0) return 0; + + + //fprintf(stdout,"%s\n",eiger_back_message); + if(eiger_back_ret_val>0){ + int i=0; + eiger_back_message[1]='\0'; + if(atoi(eiger_back_message)!=0) return 0; + + for(i=2;i <1GbE(0) or 10GbE(1)> +int EigerSetupTableEntryLeft(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport){ + char src_mac[50], src_ip[50],dst_mac[50], dst_ip[50]; + + int src_port = 0xE185; + int dst_port = udpport; + sprintf(src_ip,"%d.%d.%d.%d",(detipad>>24)&0xff,(detipad>>16)&0xff,(detipad>>8)&0xff,(detipad)&0xff); + sprintf(dst_ip,"%d.%d.%d.%d",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff); + sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((detectormacadd>>40)&0xFF), + (unsigned int)((detectormacadd>>32)&0xFF), + (unsigned int)((detectormacadd>>24)&0xFF), + (unsigned int)((detectormacadd>>16)&0xFF), + (unsigned int)((detectormacadd>>8)&0xFF), + (unsigned int)((detectormacadd>>0)&0xFF)); + sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((macad>>40)&0xFF), + (unsigned int)((macad>>32)&0xFF), + (unsigned int)((macad>>24)&0xFF), + (unsigned int)((macad>>16)&0xFF), + (unsigned int)((macad>>8)&0xFF), + (unsigned int)((macad>>0)&0xFF)); + + printf("Seting up Table Entry Left:\n"); + printf("src_port:%d\n",src_port); + printf("dst_port:%d\n",dst_port); + printf("src_ip:%s\n",src_ip); + printf("dst_ip:%s\n",dst_ip); + printf("src_mac:%s\n",src_mac); + printf("dst_mac:%s\n\n",dst_mac); + + + + eiger_back_ret_val=0; + eiger_back_message_length = sprintf(eiger_back_message,"setuptableentry %d %d %d %s %s %d %s %s %d",34,ten_giga,0,src_mac,src_ip,src_port,dst_mac,dst_ip,dst_port); + return EigerBackSendCMD(); +} + + +int EigerSetupTableEntryRight(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport){ + char src_mac[50], src_ip[50],dst_mac[50], dst_ip[50]; + + int src_port = 0xE185; + int dst_port = udpport+1; + sprintf(src_ip,"%d.%d.%d.%d",(detipad>>24)&0xff,(detipad>>16)&0xff,(detipad>>8)&0xff,(detipad)&0xff); + sprintf(dst_ip,"%d.%d.%d.%d",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff); + sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((detectormacadd>>40)&0xFF), + (unsigned int)((detectormacadd>>32)&0xFF), + (unsigned int)((detectormacadd>>24)&0xFF), + (unsigned int)((detectormacadd>>16)&0xFF), + (unsigned int)((detectormacadd>>8)&0xFF), + (unsigned int)((detectormacadd>>0)&0xFF)); + sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((macad>>40)&0xFF), + (unsigned int)((macad>>32)&0xFF), + (unsigned int)((macad>>24)&0xFF), + (unsigned int)((macad>>16)&0xFF), + (unsigned int)((macad>>8)&0xFF), + (unsigned int)((macad>>0)&0xFF)); + + printf("Seting up Table Entry Right:\n"); + printf("src_port:%d\n",src_port); + printf("dst_port:%d\n",dst_port); + printf("src_ip:%s\n",src_ip); + printf("dst_ip:%s\n",dst_ip); + printf("src_mac:%s\n",src_mac); + printf("dst_mac:%s\n\n",dst_mac); + + eiger_back_ret_val=0; + eiger_back_message_length = sprintf(eiger_back_message,"setuptableentry %d %d %d %s %s %d %s %s %d",34,ten_giga,32,src_mac,src_ip,src_port,dst_mac,dst_ip,dst_port); + return EigerBackSendCMD(); +} + + + + +int RequestImages(){ + printf("Going to request images\n"); + eiger_back_ret_val=0; + eiger_back_message_length = sprintf(eiger_back_message,"requestimages %d",0); // dst_number + return EigerBackSendCMD(); +} + +int SetDestinationParameters(int i){ + eiger_back_ret_val=0; + eiger_back_message_length = sprintf(eiger_back_message,"setdstparameters %d %d %d",ten_giga,1,i);// number of dsts + return EigerBackSendCMD(); +} + + +void SetTenGigbaBitEthernet(int val){ + ten_giga = val; +} + + +int GetTenGigbaBitEthernet(){ + return ten_giga; +} diff --git a/slsDetectorSoftware/eigerDetectorServer/EigerHighLevelFunctions.c b/slsDetectorSoftware/eigerDetectorServer/EigerHighLevelFunctions.c new file mode 100644 index 000000000..445a9a2cb --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/EigerHighLevelFunctions.c @@ -0,0 +1,363 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + +#include +#include +#include +#include + +#include "slsDetectorServer_defs.h" //include port number + + + +int eiger_nexposures = 1; +float eiger_exposuretime = 0; +float eiger_exposureperiod = 0; +int eiger_ncycles = 1; +int eiger_ngates = 0; +int eiger_getphotonenergy = 0; +int eiger_dynamicrange = 0; +int eiger_readoutspeed = 0; +int eiger_readoutmode = 0; +int eiger_highvoltage = 0; +int eiger_iodelay = 0; +int eiger_triggermode = 0; +int eiger_extgating = 0; +int eiger_extgatingpolarity = 0; + +const unsigned int ndacs = 16; +const char* dac_names[16] = {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"}; + +int saved_trimbits[256*256*4]; + + +int EigerGetNumberOfExposures(){return eiger_nexposures;} +float EigerGetExposureTime(){return eiger_exposuretime;} +float EigerGetExposurePeriod(){return eiger_exposureperiod;} +int EigerGetNumberOfCycles(){return eiger_ncycles;} +/*int EigerGetNumberOfGates(){return eiger_ngates;}*/ +unsigned int EigerGetDynamicRange(){return eiger_dynamicrange;} +int EigerGetPhotonEnergy(){return eiger_getphotonenergy;} +int EigerGetReadoutSpeed(){return eiger_readoutspeed;} +int EigerGetReadoutMode(){return eiger_readoutmode;} +int EigerGetHighVoltage(){return eiger_highvoltage;} +int EigerGetIODelay(){return eiger_iodelay;} +int EigerGetTriggerMode(){return eiger_triggermode;} +int EigerGetExternalGating(){return eiger_extgating;} +int EigerGetExternalGatingPolarity(){return eiger_extgatingpolarity;} + +int EigerInit(){ + saved_trimbits[0] = -1; + + +} + + +int EigerSendCMD(){ + if(!EigerInit()||eiger_message_length<=0) return 0; + + int sockfd = socket(AF_INET,SOCK_STREAM,0); + if(sockfd<0){ + fprintf(stderr,"ERROR opening socket\n"); + return 0; + } + + if(connect(sockfd,(struct sockaddr *) &eiger_socket_addr,sizeof(eiger_socket_addr))<0){ + fprintf(stderr,"ERROR connecting\n"); + return 0; + } + + int n = write(sockfd,eiger_message,eiger_message_length); + + int ret_length = read(sockfd,eiger_message,eiger_max_message_length); + + close(sockfd); + + if(n<0||ret_length<0) return 0; + + + //fprintf(stdout,"%s\n",eiger_message); + if(eiger_ret_val>0){ + int i=0; + eiger_message[1]='\0'; + if(atoi(eiger_message)!=0) return 0; + + for(i=2;i0&&ireadout ->expose -> ..., with store is always closed +#define DAQ_NEXPOSURERS_PARALLEL_MODE 0x00600000 //parallel acquire/read mode + +//DAQ_NEXPOSURERS_READOUT_COMPLETE_IMAGES is old now hard-wired in the firmware that every image comes with a header +//#define DAQ_NEXPOSURERS_READOUT_COMPLETE_IMAGES 0x00800000 //DAQ_IGNORE_INITIAL_CRAP and DAQ_CLKOUT_LAST_4_BITS_AND_RETURN_TO_START + +#define DAQ_NEXPOSURERS_EXTERNAL_ENABLING 0x01000000 +#define DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY 0x02000000 +#define DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY 0x04000000 + +#define DAQ_NEXPOSURERS_INTERNAL_ACQUISITION 0x00000000 //internally controlled +#define DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START 0x08000000 //external acquisition start +#define DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START 0x10000000 //external image start +#define DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP 0x18000000 //externally controlly, external image start and stop + +#define DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING 0x20000000 +#define DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION 0x40000000 + +//#define DAQ_MASTER_HALF_MODULE 0x80000000 currently not used + + +//chips static bits +#define DAQ_STATIC_BIT_PROGRAM 0x00000001 +#define DAQ_STATIC_BIT_M4 0x00000002 //these are the status bits, not bit mode +#define DAQ_STATIC_BIT_M8 0x00000004 //these are the status bits, not bit mode +#define DAQ_STATIC_BIT_M12 0x00000000 //these are the status bits, not bit mode, ie. "00" is 12 bit mode +#define DAQ_STATIC_BIT_CHIP_TEST 0x00000008 +#define DAQ_STATIC_BIT_ROTEST 0x00000010 +#define DAQ_CS_BAR_LEFT 0x00000020 +#define DAQ_CS_BAR_RIGHT 0x00000040 + + +//status flags +#define DAQ_STATUS_DAQ_RUNNING 0x01 +#define DAQ_DATA_COLLISION_ERROR 0x02 + +#define DAQ_STATUS_CURRENT_M4 0x04 +#define DAQ_STATUS_CURRENT_M8 0x08 +#define DAQ_STATUS_CURRENT_M12 0x00 //in 12 bit mode both are cleared +#define DAQ_STATUS_CURRENT_TESTMODE 0x10 +#define DAQ_STATUS_TOKEN_OUT 0x20 +#define DAQ_STATUS_SERIAL_OUT 0x40 +#define DAQ_STATUS_PIXELS_ARE_ENABLED 0x80 +#define DAQ_STATUS_DAQ_RUN_TOGGLE 0x200 + +//data delay registers +#define CHIP_DATA_OUT_DELAY_REG_CTRL 1 +#define CHIP_DATA_OUT_DELAY_REG2 2 +#define CHIP_DATA_OUT_DELAY_REG3 3 +#define CHIP_DATA_OUT_DELAY_REG4 4 +#define CHIP_DATA_OUT_DELAY_SET 0x20000000 + + +//module configuration +#define TOP_BIT_MASK 0x00f +#define MASTER_BIT_MASK 0x200 diff --git a/slsDetectorSoftware/eigerDetectorServer/EigerTest.cxx b/slsDetectorSoftware/eigerDetectorServer/EigerTest.cxx new file mode 100644 index 000000000..4e95bd560 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/EigerTest.cxx @@ -0,0 +1,38 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + +#include +#include + +#include + +#include "Eiger.h" + + +using namespace std; + +int main(int argc, char* argv[]){ + + cout<<"\n\n\n\n\n\n\n\n\n\n"<1) ? atoi(argv[1]):5; + + //Feb *f = new Feb(); + // f->Test(); + //delete f; + //return 0; + + Eiger* e = new Eiger(); + e->SetNImages(n); + e->SetDynamicRange(32); + e->SetExposureTime(0.02); + e->SetExposurePeriod(0.050); + e->StartAcquisition(); + + delete e; + + return 0; +} diff --git a/slsDetectorSoftware/eigerDetectorServer/Feb.c b/slsDetectorSoftware/eigerDetectorServer/Feb.c new file mode 100644 index 000000000..fb9ef7c67 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Feb.c @@ -0,0 +1,335 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + + +/*#include +#include */ + +#include +#include +#include + + +#include "xparameters.h" +#include "Feb.h" + + + +void Feb_Feb(){ + + Feb_nfebs = 0; + Feb_feb_numb = 0; + + Feb_send_ndata = 0; + Feb_send_buffer_size = 1026; + Feb_send_data_raw = malloc((Feb_send_buffer_size+1)*sizeof(int)); + Feb_send_data = &Feb_send_data_raw[1]; + + Feb_recv_ndata = 0; + Feb_recv_buffer_size = 1026; + Feb_recv_data_raw = malloc((Feb_recv_buffer_size+1)*sizeof(int)); + Feb_recv_data = &Feb_recv_data_raw[1]; + + Local_LocalLinkInterface1(ll,XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); + +} +/* +~Feb(){ + delete ll; + if(feb_numb) delete [] feb_numb; + delete [] send_data_raw; + delete [] recv_data_raw; +} +*/ + +void Feb_SendCompleteFebList(unsigned int n,unsigned int* list){ + unsigned int i; + if(Feb_feb_numb) free(Feb_feb_numb); + Feb_nfebs = n; + Feb_feb_numb = malloc(n*sizeof(unsigned int)); + for(i=0;i0xfff) return 0; + + Feb_send_data_raw[0] = 0x90000000 | (ch<<16); //we + if(Local_Write(ll,4,Feb_send_data_raw)!=4) return 0; + + Feb_send_data_raw[0] = 0xc0000000; //data + return 1;//((Feb_send_ndata+1)*4==Local_Write(ll,(Feb_send_ndata+1)*4,Feb_send_data_raw)); +} + +int Feb_ReadFrom(unsigned int ch, unsigned int ntrys){ + unsigned int t; + if(ch>=0xfff) return 0; + + Feb_recv_data_raw[0] = 0xa0000000 | (ch<<16); //read data + Local_Write(ll,4,Feb_recv_data_raw); + usleep(20); + + Feb_recv_ndata=-1; + for(t=0;t0){ + Feb_recv_ndata--; + break; + } + printf("\t Read try number: %d\n",t); + usleep(1000); + } + + + return (Feb_recv_ndata>=0); +} + +void Feb_PrintData(){ + int i; + printf("Sent data: %d\n",Feb_send_ndata); + for(i=0;i1&&Feb_recv_ndata>1){ + printf("\t\t Tail sent: %d (0x%x) receiver: %d (0x%x)\n",Feb_send_data[Feb_send_ndata-1],Feb_send_data[Feb_send_ndata-1],Feb_recv_data[Feb_recv_ndata-1],Feb_recv_data[Feb_recv_ndata-1]); + }else{ + printf("Error printing tail, too little data nsent = 0x%x, nrecv = 0x%x.\n",Feb_send_ndata, Feb_recv_ndata); + } + Feb_PrintData(); + } + return header_returned_is_ok; +} + + +int Feb_CheckTail(unsigned int valid_bit_mask){ + if(Feb_send_ndata<=1&&Feb_recv_ndata<=1){ + printf("Error checking tail, too little data nsent = %d, nrecv = %d.\n",Feb_send_ndata, Feb_recv_ndata); + return 0; + } + + unsigned int the_tail = Feb_recv_data[Feb_recv_ndata-1]&valid_bit_mask; + if(the_tail!=0){ + printf("Error returned in tail: 0x%x (%d)\n",the_tail,the_tail); + if(the_tail&0x10000000) printf("\t\tBusy flag address error.\n"); + if(the_tail&0x20000000) printf("\t\tRead register address error.\n"); + if(the_tail&0x40000000) printf("\t\tWrite register address error.\n"); + if(the_tail&0x80000000) printf("\t\tBram number error.\n"); + if(the_tail&0x08000000) printf("\t\tFifo to read from error.\n"); + if(the_tail&0x3ff) printf("\t\tNumber of data send error.\n"); + return 0; //error + } + + return 1; +} + + +int Feb_CheckCommunication(){ + Feb_send_data_raw[0] = 0x8fff0000; //rst-all serial coms and lls + if(Local_Write(ll,4,Feb_send_data_raw)!=4) return 0; + + printf("CheckingCommunication ....\n"); + while((Local_Read(ll,Feb_recv_buffer_size*4,Feb_recv_data_raw)/4)>0) printf("\t) Cleanning buffer ...\n"); + + return Feb_SetByteOrder(); +} + + +int Feb_SetByteOrder(){ + + unsigned int i; + Feb_send_ndata = 2; + Feb_send_data[0] = 0; //header + Feb_send_data[1] = 0; //tail + + unsigned int dst = 0xff; + for( i=0;i=nfebs){ + cout<<"Error invalid sub number "<Feb_send_buffer_size-2) return 0; + + Feb_send_ndata = nreads+2; + Feb_send_data[0] = 0x20000000 | nreads << 14; //cmd -> read "00" , nreads + + for(i=0;iFeb_send_buffer_size-2) return 0; + + //cout<<"Write register : "< write nwrites and how many + Feb_send_data[2*nwrites+1] = 0; //tail + + for(i=0;iFeb_send_buffer_size-2) return 0; + + Feb_send_ndata = nwrites+2; + Feb_send_data[0] = 0xc0000000 | mem_num << 24 | nwrites << 14 | start_address; //cmd -> write to memory, nwrites, mem number, start address + Feb_send_data[nwrites+1] = 0; //tail + for(i=0;i +#include +//#include +//#include +//#include +//#include + +#include "xparameters.h" + +#include "Feb.h" + +using namespace std; + +Feb::Feb(){ + + nfebs = 0; + feb_numb = 0; + + send_ndata = 0; + send_buffer_size = 1026; + send_data_raw = new unsigned int [send_buffer_size+1]; + send_data = &send_data_raw[1]; + + recv_ndata = 0; + recv_buffer_size = 1026; + recv_data_raw = new unsigned int [recv_buffer_size+1]; + recv_data = &recv_data_raw[1]; + + ll = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); + +} + +Feb::~Feb(){ + delete ll; + if(feb_numb) delete [] feb_numb; + delete [] send_data_raw; + delete [] recv_data_raw; +} + +void Feb::SendCompleteFebList(unsigned int n,unsigned int* list){ + if(feb_numb) delete [] feb_numb; + nfebs = n; + feb_numb = new unsigned int [n]; + for(unsigned int i=0;i0xfff) return 0; + + send_data_raw[0] = 0x90000000 | (ch<<16); //we + if(ll->Write(4,send_data_raw)!=4) return 0; + + send_data_raw[0] = 0xc0000000; //data + return ((send_ndata+1)*4==ll->Write((send_ndata+1)*4,send_data_raw)); +} + +bool Feb::ReadFrom(unsigned int ch, unsigned int ntrys){ + if(ch>=0xfff) return 0; + + recv_data_raw[0] = 0xa0000000 | (ch<<16); //read data + ll->Write(4,recv_data_raw); + usleep(20); + + recv_ndata=-1; + for(unsigned int t=0;tRead(recv_buffer_size*4,recv_data_raw)/4)>0){ + recv_ndata--; + break; + } + cout<<"\t Read try number: "<=0); +} + +void Feb::PrintData(){ + cout<<"Sent data: "<1&&recv_ndata>1){ + cout<<"\t\t Tail sent: "<Write(4,send_data_raw)!=4) return 0; + + cout<<"Feb::CheckingCommunication ...."<Read(recv_buffer_size*4,recv_data_raw)/4)>0) cout<<"\t) Cleanning buffer ..."<=nfebs){ + cout<<"Error invalid sub number "<send_buffer_size-2) return 0; + + send_ndata = nreads+2; + send_data[0] = 0x20000000 | nreads << 14; //cmd -> read "00" , nreads + + for(unsigned int i=0;isend_buffer_size-2) return 0; + + //cout<<"Write register : "< write nwrites and how many + send_data[2*nwrites+1] = 0; //tail + + for(unsigned int i=0;isend_buffer_size-2) return 0; + + send_ndata = nwrites+2; + send_data[0] = 0xc0000000 | mem_num << 24 | nwrites << 14 | start_address; //cmd -> write to memory, nwrites, mem number, start address + send_data[nwrites+1] = 0; //tail + for(unsigned int i=0;i +#include +#include +#include +#include +#include + +//#include +//#include +//#include +//#include + + + +#include "FebRegisterDefs.h" +#include "FebControl.h" +#include "Beb.h" + + + +//GetDAQStatusRegister(512,current_mode_bits_from_fpga)){ + +unsigned int Module_ndacs = 16; +char Module_dac_names[16][10]= {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"};; + + + + +struct Module modules[10]; +int moduleSize = 0; + +unsigned int Feb_Control_staticBits; //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 +unsigned int Feb_Control_acquireNReadoutMode; //safe or parallel, half or full speed +unsigned int Feb_Control_triggerMode; //internal timer, external start, external window, signal polarity (external trigger and enable) +unsigned int Feb_Control_externalEnableMode; //external enabling engaged and it's polarity +unsigned int Feb_Control_subFrameMode; + + +unsigned int Feb_Control_nimages; +double Feb_Control_exposure_time_in_sec; +int64_t Feb_Control_subframe_exposure_time_in_10nsec; +double Feb_Control_exposure_period_in_sec; + +int64_t Feb_Control_RateTable_Tau_in_nsec = -1; +int64_t Feb_Control_RateTable_Subexptime_in_nsec = -1; + +unsigned int Feb_Control_trimbit_size; +unsigned int* Feb_Control_last_downloaded_trimbits; + + +int Feb_Control_module_number; +int Feb_Control_current_index; + +int Feb_Control_counter_bit = 1; +int Feb_control_master = 0; + +unsigned int Feb_Control_rate_correction_table[1024]; +double Feb_Control_rate_meas[16384]; + +int Feb_Control_activated = 1; + + +void Module_Module(struct Module* mod,unsigned int number, unsigned int address_top){ + unsigned int i; + mod->module_number = number; + mod->top_address_valid = 1; + mod->top_left_address = 0x100 | (0xff & address_top); + mod->top_right_address = (0x200 | (0xff & address_top)); + mod-> bottom_address_valid = 0; + mod-> bottom_left_address = 0; + mod-> bottom_right_address = 0; + + mod->high_voltage = -1; + mod->top_dac = malloc(Module_ndacs * sizeof(int)); + mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); + for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; + for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; +} + + +void Module_ModuleBottom(struct Module* mod,unsigned int number, unsigned int address_bottom){ + unsigned int i; + mod->module_number = number; + mod->top_address_valid = 0; + mod->top_left_address = 0; + mod->top_right_address = 0; + mod-> bottom_address_valid = 1; + mod-> bottom_left_address = 0x100 | (0xff & address_bottom); + mod-> bottom_right_address = (0x200 | (0xff & address_bottom)); + + mod->high_voltage = -1; + + for(i=0;i<4;i++) mod->idelay_top[i]=mod->idelay_bottom[i]=0; + + mod->top_dac = malloc(Module_ndacs * sizeof(int)); + mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); + for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; + for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; +} + + + +void Module_Module1(struct Module* mod,unsigned int number, unsigned int address_top, unsigned int address_bottom){ + unsigned int i; + mod->module_number = number; + mod->top_address_valid = 1; + mod->top_left_address = 0x100 | (0xff & address_top); + mod->top_right_address = 0x200 | (0xff & address_top); + mod->bottom_address_valid = 1; + mod->bottom_left_address = 0x100 | (0xff & address_bottom); + mod->bottom_right_address = 0x200 | (0xff & address_bottom); + + mod->high_voltage = -1; + + for(i=0;i<4;i++) mod->idelay_top[i]=mod->idelay_bottom[i]=0; + + mod->top_dac = malloc(Module_ndacs * sizeof(int)); + mod->bottom_dac = malloc(Module_ndacs * sizeof(int)); + for(i=0;itop_dac[i] = mod->top_address_valid ? -1:0; + for(i=0;ibottom_dac[i] = mod->bottom_address_valid ? -1:0; +} + + +unsigned int Module_GetModuleNumber(struct Module* mod) {return mod->module_number;} +int Module_TopAddressIsValid(struct Module* mod) {return mod->top_address_valid;} +unsigned int Module_GetTopBaseAddress(struct Module* mod) {return (mod->top_left_address&0xff);} +unsigned int Module_GetTopLeftAddress(struct Module* mod) {return mod->top_left_address;} +unsigned int Module_GetTopRightAddress(struct Module* mod) {return mod->top_right_address;} +unsigned int Module_GetBottomBaseAddress(struct Module* mod) {return (mod->bottom_left_address&0xff);} +int Module_BottomAddressIsValid(struct Module* mod) {return mod->bottom_address_valid;} +unsigned int Module_GetBottomLeftAddress(struct Module* mod) {return mod->bottom_left_address;} +unsigned int Module_GetBottomRightAddress(struct Module* mod) {return mod->bottom_right_address;} + +unsigned int Module_SetTopIDelay(struct Module* mod,unsigned int chip,unsigned int value) { return Module_TopAddressIsValid(mod) &&chip<4 ? (mod->idelay_top[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr +unsigned int Module_GetTopIDelay(struct Module* mod,unsigned int chip) { return chip<4 ? mod->idelay_top[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr +unsigned int Module_SetBottomIDelay(struct Module* mod,unsigned int chip,unsigned int value) { return Module_BottomAddressIsValid(mod) &&chip<4 ? (mod->idelay_bottom[chip]=value) : 0;} //chip 0=ll,1=lr,0=rl,1=rr +unsigned int Module_GetBottomIDelay(struct Module* mod,unsigned int chip) { return chip<4 ? mod->idelay_bottom[chip] : 0;} //chip 0=ll,1=lr,0=rl,1=rr + +float Module_SetHighVoltage(struct Module* mod,float value) { return Feb_control_master ? (mod->high_voltage=value) : -1;}// Module_TopAddressIsValid(mod) ? (mod->high_voltage=value) : -1;} +float Module_GetHighVoltage(struct Module* mod) { return mod->high_voltage;} + +int Module_SetTopDACValue(struct Module* mod,unsigned int i, int value) { return (itop_dac[i]=value) : -1;} +int Module_GetTopDACValue(struct Module* mod,unsigned int i) { return (itop_dac[i] : -1;} +int Module_SetBottomDACValue(struct Module* mod,unsigned int i, int value) { return (ibottom_dac[i]=value): -1;} +int Module_GetBottomDACValue(struct Module* mod,unsigned int i) { return (ibottom_dac[i] : -1;} + + + +void Feb_Control_activate(int activate){ + Feb_Control_activated = activate; +} + +int Feb_Control_IsBottomModule(){ + if(Module_BottomAddressIsValid(&modules[Feb_Control_current_index])) + return 1; + return 0; +} + + +int Feb_Control_GetModuleNumber(){ + return Feb_Control_module_number; +} + + +void Feb_Control_FebControl(){ + Feb_Control_staticBits=Feb_Control_acquireNReadoutMode=Feb_Control_triggerMode=Feb_Control_externalEnableMode=Feb_Control_subFrameMode=0; + Feb_Control_trimbit_size=263680; + Feb_Control_last_downloaded_trimbits = malloc(Feb_Control_trimbit_size * sizeof(int)); + moduleSize = 0; +} + + + + +int Feb_Control_Init(int master, int top, int module_num){ + unsigned int i; + Feb_Control_module_number = 0; + Feb_Control_current_index = 0; + Feb_control_master = master; + + //global send + Feb_Control_AddModule1(0,1,0xff,0,1); + Feb_Control_PrintModuleList(); + Feb_Control_module_number = (module_num & 0xFF); + + int serial = !top; + printf("serial: %d\n",serial); + + Feb_Control_current_index = 1; + + + //Add the half module + Feb_Control_AddModule1(Feb_Control_module_number,top,serial,serial,1); + Feb_Control_PrintModuleList(); + + + unsigned int nfebs = 0; + unsigned int* feb_list = malloc(moduleSize*4 * sizeof(unsigned int)); + for(i=1;i3){ + cprintf(RED,"Error SetIDelay chip_pos %d doesn't exist.\n",chip_pos);; + return 0; + } + + unsigned int module_index=0; + if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ + cprintf(RED,"Error could not set i delay module number %d invalid.\n",module_num); + return 0; + } + + int ok = 1; + if(chip_pos/2==0){ //left fpga + if(Module_TopAddressIsValid(&modules[module_index])){ + if(Feb_Control_SendIDelays(Module_GetTopLeftAddress(&modules[module_index]),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) Module_SetTopIDelay(&modules[module_index],chip_pos,ndelay_units); + else{ + for(i=0;i0x3ff) ndelay_units=0x3ff; + // this is global + unsigned int delay_data_valid_nclks = 15 - ((ndelay_units&0x3c0)>>6); //data valid delay upto 15 clks + ndelay_units &= 0x3f; + + unsigned int set_left_delay_channels = chip_lr ? channels:0; + unsigned int set_right_delay_channels = chip_lr ? 0:channels; + + printf("\tSetting delays of "); + if(set_left_delay_channels!=0) printf("left chips of dst_num %d",dst_num); + else if(set_right_delay_channels!=0) printf("right chips of dst_num %d",dst_num); + + printf(", tracks 0x%x to: %d, %d clks and %d units.\n",channels,(((15-delay_data_valid_nclks)<<6)|ndelay_units),delay_data_valid_nclks,ndelay_units); + + if(Feb_Control_activated){ + if(!Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG2, 1<<31 | delay_data_valid_nclks<<16 | ndelay_units,0,0) || //the 1<<31 time enables the setting of the data valid delays + !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG3,set_left_delay_channels,0,0) || + !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG4,set_right_delay_channels,0,0) || + !Feb_Interface_WriteRegister(dst_num,CHIP_DATA_OUT_DELAY_REG_CTRL,CHIP_DATA_OUT_DELAY_SET,1,1)){ + cprintf(RED,"Warning: could not SetChipDataInputDelays(...).\n"); + return 0; + } + } + + return 1; +} + + +int Feb_Control_VoltageToDAC(float value, unsigned int* digital,unsigned int nsteps,float vmin,float vmax){ + if(valuevmax) return 0; + *digital = (int)(((value-vmin)/(vmax-vmin))*(nsteps-1) + 0.5); + return 1; +} + +float Feb_Control_DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax){ + return vmin+(vmax-vmin)*digital/(nsteps-1); +} + + +int Feb_Control_SetHighVoltage(float value){ + return Feb_Control_SetHighVoltage1(Feb_Control_module_number,value); +} + +int Feb_Control_SetHighVoltage1(unsigned int module_num,float value){ + unsigned int module_index=0; + unsigned int i; + + if(Feb_control_master){//if(Module_TopAddressIsValid(&modules[module_index])){ + if(!Feb_Control_GetModuleIndex(module_num,&module_index)){/*||!Module_TopAddressIsValid(&modules[module_index])){*/ + cprintf(RED,"Error could not set high voltage module number %d invalid.\n",module_num); + return 0; + } + }else + return 0; + + if(!Feb_Control_SendHighVoltage(Module_GetTopRightAddress(&modules[module_index]),&value)) return 0; + + if(module_index!=0) Module_SetHighVoltage(&modules[module_index],value); + else for(i=0;i4095){ + cprintf(RED,"Warning: SetDac bad value, %d. The range is 0 to 4095.\n",v); + return 0; + } + + if(top&&Module_TopAddressIsValid(&modules[module_index])){ + + if(!Feb_Control_SendDACValue(Module_GetTopRightAddress(&modules[module_index]),dac_ch,&v)) return 0; + + + if(module_index!=0) Module_SetTopDACValue(&modules[module_index],dac_ch,v); + else for(i=0;i=Module_ndacs){ + cprintf(RED,"Warning: GetDACName index out of range, %d invalid.\n",dac_num); + return 0; + } + strcpy(s,Module_dac_names[dac_num]); + return 1; +} + +int Feb_Control_GetDACNumber(char* s, unsigned int* n){ + unsigned int i; + for(i=0;i15){ + cprintf(RED,"Warning invalid ch for SetDAC.\n"); + return 0; + } + + //if(voltage<0) return PowerDownDAC(socket_num,ch); + + *value&=0xfff; + unsigned int dac_ic = (ch<8) ? 1:2; + unsigned int dac_ch = ch%8; + unsigned int r = dac_ic<<30 | 3<<16 | dac_ch<<12 | *value; //3 write and power up + + + if(Feb_Control_activated){ + if(!Feb_Interface_WriteRegister(dst_num,0,r,1,0)){ + cprintf(RED,"Warning: trouble setting dac %d voltage.\n",ch); + return 0; + } + } + + float voltage=Feb_Control_DACToVoltage(*value,4096,0,2048); + + printf("\tDac number %d (%s) of dst %d set to %d (%f mV).\n",ch,Module_dac_names[ch],dst_num,*value,voltage); + return 1; +} + + + +int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int *trimbits){ + printf("Setting Trimbits\n"); + + //for (int iy=10000;iy<20020;++iy)//263681 + //for (int iy=263670;iy<263680;++iy)//263681 + // printf("%d:%c\t\t",iy,trimbits[iy]); + + unsigned int trimbits_to_load_l[1024]; + unsigned int trimbits_to_load_r[1024]; + + unsigned int module_index=0; + if(!Feb_Control_GetModuleIndex(module_num,&module_index)){ + cprintf(RED,"Warning could not set trimbits, bad module number.\n"); + return 0; + } + + if(!Feb_Control_Reset()) cprintf(RED,"Warning could not reset DAQ.\n"); + int l_r; //printf("222\n"); + for(l_r=0;l_r<2;l_r++){ // l_r loop + //printf("\nl_r:%d\t\t",l_r); + unsigned int disable_chip_mask = l_r ? DAQ_CS_BAR_LEFT : DAQ_CS_BAR_RIGHT; + if(Feb_Control_activated){ + if(!(Feb_Interface_WriteRegister(0xfff,DAQ_REG_STATIC_BITS,disable_chip_mask|DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_M8,0,0) + &&Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) + &&Feb_Control_StartDAQOnlyNWaitForFinish(5000))){ + printf("Could not select chips\n"); + return 0; + } + } + + int row_set; + for(row_set=0;row_set<16;row_set++){ //16 rows at a time + //printf("row_set:%d\t\t",row_set); + if(row_set==0){ + if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY|DAQ_SEND_A_TOKEN_IN|DAQ_LOAD_16ROWS_OF_TRIMBITS)){ + cprintf(RED,"Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + return 0; + } + }else{ + if(!Feb_Control_SetCommandRegister(DAQ_LOAD_16ROWS_OF_TRIMBITS)){ + cprintf(RED,"Warning: Could not Feb_Control_SetCommandRegister for loading trim bits.\n"); + return 0; + } + } + + int row; + for(row=0;row<16;row++){ //row loop + //printf("row:%d\t\t",row); + int offset = 2*32*row; + int sc; + for(sc=0;sc<32;sc++){ //supercolumn loop sc + //printf("sc:%d\t\t",sc); + int super_column_start_position_l = 1030*row + l_r *258 + sc*8; + int super_column_start_position_r = 1030*row + 516 + l_r *258 + sc*8; + + /* + int super_column_start_position_l = 1024*row + l_r *256 + sc*8; //256 per row, 8 per super column + int super_column_start_position_r = 1024*row + 512 + l_r *256 + sc*8; //256 per row, 8 per super column + */ + int chip_sc = 31 - sc; + trimbits_to_load_l[offset+chip_sc] = 0; + trimbits_to_load_r[offset+chip_sc] = 0; + trimbits_to_load_l[offset+chip_sc+32] = 0; + trimbits_to_load_r[offset+chip_sc+32] = 0; + int i; + for(i=0;i<8;i++){ // column loop i + //printf("i:%d\t\t",i); + + if(Module_TopAddressIsValid(&modules[1])){ + trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_l+i])<<((7-i)*4);//low + trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_l+i])>>3)<<((7-i)*4);//upper + trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low + trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_r+i])>>3)<<((7-i)*4);//upper + }else{ + trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])<<((7-i)*4);//low + trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])>>3)<<((7-i)*4);//upper + trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])<<((7-i)*4);//low + trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])>>3)<<((7-i)*4);//upper + + } + } // end column loop i + } //end supercolumn loop sc + } //end row loop + + if(Module_TopAddressIsValid(&modules[1])){ + if(Feb_Control_activated){ + if(!Feb_Interface_WriteMemoryInLoops(Module_GetTopLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| + !Feb_Interface_WriteMemoryInLoops(Module_GetTopRightAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_r)|| + //if(!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| + // !Feb_Interface_WriteMemory(Module_GetTopRightAddress(&modules[0]),0,0,1023,trimbits_to_load_l)|| + !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + printf(" some errror!\n"); + return 0; + } + } + }else{ + if(Feb_Control_activated){ + if(!Feb_Interface_WriteMemoryInLoops(Module_GetBottomLeftAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_l)|| + !Feb_Interface_WriteMemoryInLoops(Module_GetBottomRightAddress(&modules[Feb_Control_current_index]),0,0,1024,trimbits_to_load_r)|| + //if(!Feb_Interface_WriteMemory(Module_GetTopLeftAddress(&modules[0]),0,0,1023,trimbits_to_load_r)|| + // !Feb_Interface_WriteMemory(Module_GetTopRightAddress(&modules[0]),0,0,1023,trimbits_to_load_l)|| + !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + printf(" some errror!\n"); + return 0; + } + } + } + + } //end row_set loop (groups of 16 rows) + } // end l_r loop + + memcpy(Feb_Control_last_downloaded_trimbits,trimbits,Feb_Control_trimbit_size*sizeof(unsigned int)); + + return Feb_Control_SetStaticBits(); //send the static bits +} + + +unsigned int* Feb_Control_GetTrimbits(){ + return Feb_Control_last_downloaded_trimbits; +} + + + + +unsigned int Feb_Control_AddressToAll(){printf("in Feb_Control_AddressToAll()\n"); + + + +if(moduleSize==0) return 0; + + +if(Module_BottomAddressIsValid(&modules[1])){ + //printf("************* bottom\n"); + //if(Feb_Control_am_i_master) + return Module_GetBottomLeftAddress(&modules[1])|Module_GetBottomRightAddress(&modules[1]); + // else return 0; +} +// printf("************* top\n"); + +return Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1]); +//return Module_GetTopLeftAddress(&modules[0])|Module_GetTopRightAddress(&modules[0]); + + +} + +int Feb_Control_SetCommandRegister(unsigned int cmd){ + if(Feb_Control_activated) + return Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CHIP_CMDS,cmd,0,0); + else + return 1; +} + + +int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status){ + //if deactivated, should be handled earlier and should not get into this function + if(Feb_Control_activated){ + if(!Feb_Interface_ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)){ + cprintf(RED,"Error: reading status register.\n"); + return 0; + } + } + + *ret_status = (0x02FF0000 & *ret_status) >> 16; + return 1; +} + + +int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us){ + if(Feb_Control_activated){ + if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)||!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START,0,0)){ + cprintf(RED,"Warning: could not start.\n"); + return 0; + } + } + return Feb_Control_WaitForFinishedFlag(sleep_time_us); +} + + +int Feb_Control_AcquisitionInProgress(){ + unsigned int status_reg_r=0,status_reg_l=0; + + //deactivated should return end of acquisition + if(!Feb_Control_activated) + return 0; + + int ind = Feb_Control_current_index; + if(Module_BottomAddressIsValid(&modules[ind])){ + + if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) + {cprintf(RED,"Error: Trouble reading Status register. bottom right address\n");return 0;} + if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) + {cprintf(RED,"Error: Trouble reading Status register. bottom left address\n");return 0;} + + }else{ + if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) + {cprintf(RED,"Error: Trouble reading Status register. top right address\n");return 0;} + if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) + {cprintf(RED,"Error: Trouble reading Status register. top left address\n");return 0;} + } + + //running + if((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUNNING) {/*printf("**runningggg\n");*/ + return 1; + } + //idle + return 0; +} + + +int Feb_Control_AcquisitionStartedBit(){ + unsigned int status_reg_r=0,status_reg_l=0; + + //deactivated should return acquisition started/ready + if(!Feb_Control_activated) + return 1; + + int ind = Feb_Control_current_index; + if(Module_BottomAddressIsValid(&modules[ind])){ + + if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomRightAddress(&modules[ind]),&status_reg_r))) + {cprintf(RED,"Error: Trouble reading Status register. bottom right address\n");return -1;} + if(!(Feb_Control_GetDAQStatusRegister(Module_GetBottomLeftAddress(&modules[ind]),&status_reg_l))) + {cprintf(RED,"Error: Trouble reading Status register. bottom left address\n");return -1;} + + }else{ + if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopRightAddress(&modules[ind]),&status_reg_r))) + {cprintf(RED,"Error: Trouble reading Status register. top right address\n"); return -1;} + if(!(Feb_Control_GetDAQStatusRegister(Module_GetTopLeftAddress(&modules[ind]),&status_reg_l))) + {cprintf(RED,"Error: Trouble reading Status register. top left address\n");return -1;} + } + + //doesnt mean it started, just the bit + if((status_reg_r|status_reg_l)&DAQ_STATUS_DAQ_RUN_TOGGLE) + return 1; + + return 0; +} + + + +int Feb_Control_WaitForFinishedFlag(int sleep_time_us){ + int is_running = Feb_Control_AcquisitionInProgress(); + while(is_running){ + usleep(sleep_time_us); + is_running = Feb_Control_AcquisitionInProgress(); + } + if(is_running!=0){ + printf("\n\nWarning WaitForFinishedFlag comunication problem..\n\n"); + return 0; //communication problem + } + + return 1; +} + + +int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag){ + + //deactivated dont wait (otherwise give a toggle value back) + if(!Feb_Control_activated) + return 1; + + int value = prev_flag; + while(value == prev_flag){ + usleep(sleep_time_us); + value = Feb_Control_AcquisitionStartedBit(); + } + + //did not start + if(value == -1) + return 0; + + return 1; +} + + +int Feb_Control_Reset(){ + printf("Reset daq\n"); + if(Feb_Control_activated){ + if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_RESET,0,0) || !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CTRL,0,0,0)){ + cprintf(RED,"Warning: Could not reset daq, no response.\n"); + return 0; + } + } + + return Feb_Control_WaitForFinishedFlag(5000); +} + + + + +int Feb_Control_SetStaticBits(){ + if(Feb_Control_activated){ + //program=1,m4=2,m8=4,test=8,rotest=16,cs_bar_left=32,cs_bar_right=64 + if(!Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_STATIC_BITS,Feb_Control_staticBits,0,0) || !Feb_Control_SetCommandRegister(DAQ_SET_STATIC_BIT) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + cprintf(RED,"Warning: Could not set static bits\n"); + return 0; + } + } + + return 1; +} +int Feb_Control_SetStaticBits1(unsigned int the_static_bits){ + Feb_Control_staticBits = the_static_bits; + return Feb_Control_SetStaticBits(); +} + +int Feb_Control_SetInTestModeVariable(int on){ + if(on) Feb_Control_staticBits |= DAQ_STATIC_BIT_CHIP_TEST; //setting test bit to high + else Feb_Control_staticBits &= (~DAQ_STATIC_BIT_CHIP_TEST); //setting test bit to low + return 1; +} + +int Feb_Control_GetTestModeVariable(){ + return Feb_Control_staticBits&DAQ_STATIC_BIT_CHIP_TEST; +} + +int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo){ + static unsigned int everything_but_bit_mode = DAQ_STATIC_BIT_PROGRAM|DAQ_STATIC_BIT_CHIP_TEST|DAQ_STATIC_BIT_ROTEST; + if(four_eight_sixteen_or_thirtytwo==4){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M4 | (Feb_Control_staticBits&everything_but_bit_mode); //leave test bits in currernt state + Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else if(four_eight_sixteen_or_thirtytwo==8){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M8 | (Feb_Control_staticBits&everything_but_bit_mode); + Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else if(four_eight_sixteen_or_thirtytwo==16){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits&everything_but_bit_mode); + Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else if(four_eight_sixteen_or_thirtytwo==32){ + Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits&everything_but_bit_mode); + Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; + }else{ + cprintf(RED,"Warning: dynamic range (%d) not valid, not setting bit mode.\n",four_eight_sixteen_or_thirtytwo); + printf("Set dynamic range int must equal 4,8 16, or 32.\n"); + return 0; + } + + printf("Dynamic range set to: %d\n",four_eight_sixteen_or_thirtytwo); + return 1; +} + +unsigned int Feb_Control_GetDynamicRange(){ + if(Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) return 32; + else if(DAQ_STATIC_BIT_M4&Feb_Control_staticBits) return 4; + else if(DAQ_STATIC_BIT_M8&Feb_Control_staticBits) return 8; + + return 16; +} + +int Feb_Control_SetReadoutSpeed(unsigned int readout_speed){ //0->full,1->half,2->quarter or 3->super_slow + Feb_Control_acquireNReadoutMode &= (~DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED); + if(readout_speed==1){ + Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_HALF_SPEED; + printf("Everything at half speed, ie. reading with 50 MHz main clk (half speed) ....\n"); + }else if(readout_speed==2){ + Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_QUARTER_SPEED; + printf("Everything at quarter speed, ie. reading with 25 MHz main clk (quarter speed) ....\n"); + }else if(readout_speed==3){ + Feb_Control_acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED; + printf("Everything at super slow speed, ie. reading with ~0.200 MHz main clk (super slow speed) ....\n"); + }else{ + if(readout_speed){ + cprintf(RED,"Warning readout speed %d unknown, defaulting to full speed.\n",readout_speed); + printf("Everything at full speed, ie. reading with 100 MHz main clk (full speed) ....\n"); + return 0; + } + printf("Everything at full speed, ie. reading with 100 MHz main clk (full speed) ....\n"); + } + + return 1; +} + +int Feb_Control_SetReadoutMode(unsigned int readout_mode){ //0->parallel,1->non-parallel,2-> safe_mode + Feb_Control_acquireNReadoutMode &= (~DAQ_NEXPOSURERS_PARALLEL_MODE); + if(readout_mode==1){ + Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_NORMAL_NONPARALLEL_MODE; + printf("Readout mode set to normal non-parallel readout mode ... \n");; + }else if(readout_mode==2){ + Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_SAFEST_MODE_ROW_CLK_BEFORE_MODE; + printf("Readout mode set to safest mode, row clk before main clk readout sequence .... \n");; + }else{ + Feb_Control_acquireNReadoutMode |= DAQ_NEXPOSURERS_PARALLEL_MODE; + if(readout_mode){ + cprintf(RED,"Warning readout mode %d) unknown, defaulting to full speed.\n",readout_mode); + printf("Readout mode set to parrallel acquire/read mode .... \n");; + return 0; + } + printf("Readout mode set to parrallel acquire/read mode .... \n");; + } + + return 1; +} + +int Feb_Control_SetTriggerMode(unsigned int trigger_mode,int polarity){ + //"00"-> internal exposure time and period, + //"01"-> external acquistion start and internal exposure time and period, + //"10"-> external start trigger and internal exposure time, + //"11"-> external triggered start and stop of exposures + Feb_Control_triggerMode = (~DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP); + + if(trigger_mode == 1){ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START; + printf("Trigger mode: external start of acquisition sequence, internal exposure length and period.\n");; + }else if(trigger_mode == 2){ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START; + printf("Trigger mode: external image start, internal exposure time.\n");; + }else if(trigger_mode == 3){ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP; + printf("Trigger mode: externally controlled, external image window (start and stop).\n");; + }else{ + Feb_Control_triggerMode = DAQ_NEXPOSURERS_INTERNAL_ACQUISITION; + if(trigger_mode) cprintf(RED,"Warning trigger %d) unknown, defaulting to internal triggering.\n",trigger_mode);; + + printf("Trigger mode: acquisition internally controlled exposure length and period.\n");; + return trigger_mode==0; + } + + if(polarity){ + Feb_Control_triggerMode |= DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY; + printf("External trigger polarity set to positive.\n");; + }else{ + Feb_Control_triggerMode &= (~DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY); + printf("External trigger polarity set to negitive.\n");; + } + + return 1; +} + + +int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity){ + if(use_external_enable){ + Feb_Control_externalEnableMode |= DAQ_NEXPOSURERS_EXTERNAL_ENABLING; + printf("External enabling enabled, "); + if(polarity){ + Feb_Control_externalEnableMode |= DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY; + printf(", polarity set to positive.\n");; + }else{ + Feb_Control_externalEnableMode &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY); + printf(", polarity set to negative.\n");; + } + }else{ + Feb_Control_externalEnableMode = 0; /* changed by Dhanya according to old code &= (~DAQ_NEXPOSURERS_EXTERNAL_ENABLING);*/ + printf("External enabling disabled.\n");; + } + + return 1; +} + +int Feb_Control_SetNExposures(unsigned int n_images){ + if(!n_images){ + cprintf(RED,"Warning nimages must be greater than zero.%d\n",n_images); + return 0; + } + + Feb_Control_nimages = n_images; + printf("Number of images set to: %d\n",Feb_Control_nimages); + return 1; +} +unsigned int Feb_Control_GetNExposures(){return Feb_Control_nimages;} + +int Feb_Control_SetExposureTime(double the_exposure_time_in_sec){ + Feb_Control_exposure_time_in_sec = the_exposure_time_in_sec; + printf("Exposure time set to: %fs\n",Feb_Control_exposure_time_in_sec); + return 1; +} +double Feb_Control_GetExposureTime(){return Feb_Control_exposure_time_in_sec;} + +int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec){ + Feb_Control_subframe_exposure_time_in_10nsec = the_subframe_exposure_time_in_10nsec; + printf("Sub Frame Exposure time set to: %lld\n",(long long int)Feb_Control_subframe_exposure_time_in_10nsec); + return 1; +} +int64_t Feb_Control_GetSubFrameExposureTime(){return Feb_Control_subframe_exposure_time_in_10nsec*10;} + +int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec){ + Feb_Control_exposure_period_in_sec = the_exposure_period_in_sec; + printf("Exposure period set to: %f\n",Feb_Control_exposure_period_in_sec); + return 1; +} +double Feb_Control_GetExposurePeriod(){return Feb_Control_exposure_period_in_sec;} + +unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec){ + float n_clk_cycles = round(time_in_sec/10e-9); //200 MHz ctb clk or 100 MHz feb clk + + unsigned int decoded_time; + if(n_clk_cycles>(pow(2,29)-1)*pow(10,7)){ + float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); + cprintf(RED,"Warning: time exceeds (%f) maximum exposure time of %f sec.\n",time_in_sec,max_time); + printf("\t Setting to maximum %f us.\n",max_time); + decoded_time = 0xffffffff; + }else{ + int power_of_ten = 0; + while(n_clk_cycles>pow(2,29)-1){ power_of_ten++; n_clk_cycles = round(n_clk_cycles/10.0);} + decoded_time = (int)(n_clk_cycles)<<3 | (int)(power_of_ten); + } + + return decoded_time; +} + +int Feb_Control_ResetChipCompletely(){ + if(!Feb_Control_SetCommandRegister(DAQ_RESET_COMPLETELY) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + cprintf(RED,"Warning: could not ResetChipCompletely() with 0x%x.\n",DAQ_RESET_COMPLETELY); + return 0; + } + printf("Chip reset completely\n"); + return 1; +} + + + +int Feb_Control_ResetChipPartially(){ + if(!Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + cprintf(RED,"Warning: could not ResetChipPartially with periphery\n"); + return 0; + } + printf("Chip reset periphery 0x%x\n",DAQ_RESET_PERIPHERY); + + if(!Feb_Control_SetCommandRegister(DAQ_RESET_COLUMN_SELECT) || !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + cprintf(RED,"Warning: could not ResetChipPartially with column select\n"); + return 0; + } + printf("Chip reset column select 0x%x\n",DAQ_RESET_COLUMN_SELECT); + + return 1; +} + + +void Feb_Control_PrintAcquisitionSetup(){ + + time_t rawtime; + time(&rawtime); + struct tm *timeinfo = localtime(&rawtime); + + printf("\nStarting an exposure: %s",asctime(timeinfo)); + printf("\t Dynamic range nbits: %d\n",Feb_Control_GetDynamicRange()); + printf("\t Trigger mode: 0x%x\n",Feb_Control_triggerMode); + printf("\t Number of exposures: %d\n",Feb_Control_GetNExposures()); + printf("\t Exsposure time (if used): %f seconds.\n",Feb_Control_exposure_time_in_sec); + printf("\t Exsposure period (if used): %f seconds.\n\n\n",Feb_Control_exposure_period_in_sec); +} + +int Feb_Control_SendBitModeToBebServer(){ + + unsigned int just_bit_mode = (DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8) & Feb_Control_staticBits; + unsigned int bit_mode = 16; //default + if(just_bit_mode == DAQ_STATIC_BIT_M4) bit_mode = 4; + else if(just_bit_mode == DAQ_STATIC_BIT_M8) bit_mode = 8; + else if(Feb_Control_subFrameMode&DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) bit_mode = 32; + + + if(!Beb_SetUpTransferParameters(bit_mode)){ + cprintf(RED,"Error: sending bit mode ...\n"); + return 0; + } + + return 1; +} + + +int Feb_Control_PrepareForAcquisition(){//return 1; + static unsigned int reg_nums[20]; + static unsigned int reg_vals[20]; + + Feb_Control_PrintAcquisitionSetup(); + + // if(!Reset()||!ResetDataStream()){ + if(!Feb_Control_Reset()){ + printf("Trouble reseting daq or data stream...\n");; + return 0; + } + + if(!Feb_Control_SetStaticBits1(Feb_Control_staticBits&(DAQ_STATIC_BIT_M4|DAQ_STATIC_BIT_M8))){ + printf("Trouble setting static bits ...\n");; + return 0; + } + + if(!Feb_Control_SendBitModeToBebServer()){ + printf("Trouble sending static bits to server ...\n");; + return 0; + } + + int ret=0; + if(Feb_Control_counter_bit) + ret = Feb_Control_ResetChipCompletely(); + else + ret = Feb_Control_ResetChipPartially(); + if(!ret){ + printf("Trouble resetting chips ...\n");; + return 0; + } + + + reg_nums[0]=DAQ_REG_CTRL; + reg_vals[0]=0; + reg_nums[1]=DAQ_REG_NEXPOSURES; + reg_vals[1]=Feb_Control_nimages; + reg_nums[2]=DAQ_REG_EXPOSURE_TIMER; + reg_vals[2]=Feb_Control_ConvertTimeToRegister(Feb_Control_exposure_time_in_sec); + reg_nums[3]=DAQ_REG_EXPOSURE_REPEAT_TIMER; + reg_vals[3]=Feb_Control_ConvertTimeToRegister(Feb_Control_exposure_period_in_sec); + reg_nums[4]=DAQ_REG_CHIP_CMDS; + reg_vals[4]=(Feb_Control_acquireNReadoutMode|Feb_Control_triggerMode|Feb_Control_externalEnableMode|Feb_Control_subFrameMode); + reg_nums[5]=DAQ_REG_SUBFRAME_EXPOSURES; + reg_vals[5]= Feb_Control_subframe_exposure_time_in_10nsec; //(1 means 10ns, 100 means 1000ns) + // if(!Feb_Interface_WriteRegisters((Module_GetTopLeftAddress(&modules[1])|Module_GetTopRightAddress(&modules[1])),20,reg_nums,reg_vals,0,0)){ + if(Feb_Control_activated){ + if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),6,reg_nums,reg_vals,0,0)){ + printf("Trouble starting acquisition....\n");; + return 0; + } + } + + return 1; +} + + + +int Feb_Control_StartAcquisition(){ + printf("****** starting acquisition********* \n"); + + static unsigned int reg_nums[20]; + static unsigned int reg_vals[20]; + + + int i; + for(i=0;i<14;i++){ + reg_nums[i]=DAQ_REG_CTRL; + reg_vals[i]=0; + } + reg_nums[14]=DAQ_REG_CTRL; + reg_vals[14]=ACQ_CTRL_START; + + if(Feb_Control_activated){ + if(!Feb_Interface_WriteRegisters(Feb_Control_AddressToAll(),15,reg_nums,reg_vals,0,0)){ + cprintf(RED,"Trouble starting acquisition....\n");; + return 0; + } + } + + + return 1; +} + +int Feb_Control_StopAcquisition(){ + return Feb_Control_Reset(); +} + + + +int Feb_Control_SaveAllTrimbitsTo(int value){ + unsigned int chanregs[Feb_Control_trimbit_size]; + int i; + for(i=0;i255||y<0||y>255){ + cprintf(RED,"Warning: Pixel out of range.\n"); + return 0; + } + + // y = 255 - y; + int nrowclocks = 0; + nrowclocks += (Feb_Control_staticBits&DAQ_STATIC_BIT_M4) ? 0 : 2*y; + nrowclocks += (Feb_Control_staticBits&DAQ_STATIC_BIT_M8) ? 0 : y; + + Feb_Control_SetInTestModeVariable(1); //on + Feb_Control_SetStaticBits(); + Feb_Control_SetCommandRegister(DAQ_RESET_PERIPHERY|DAQ_RESET_COLUMN_SELECT); + Feb_Control_StartDAQOnlyNWaitForFinish(5000); + + unsigned int serial_in = 8<<(4*(7-x%8)); + if(!Feb_Control_Shift32InSerialIn(serial_in)){ + cprintf(RED,"Warning ChipController::PulsePixel: could shift in the initail 32.\n"); + return 0; + } + + if(!pulse_multiple) + serial_in=0; + for(i=0;i1023){ + cprintf(RED,"Warning: Clock row clock ntimes (%d) exceeds the maximum value of 1023.\n\t Setting ntimes to 1023.\n",ntimes); + ntimes=1023; + } + + if(Feb_Control_activated){ + if(!Feb_Control_SetCommandRegister(DAQ_CLK_ROW_CLK_NTIMES) || + !Feb_Interface_WriteRegister(Feb_Control_AddressToAll(),DAQ_REG_CLK_ROW_CLK_NTIMES,ntimes,0,0) || + !Feb_Control_StartDAQOnlyNWaitForFinish(5000)){ + cprintf(RED,"Warning: could not clock row clock.\n"); + return 0; + } + } + + return 1; +} + + +int Feb_Control_PulseChip(int npulses){ + int i; + int on = 1; + + if(npulses == -1){ + on = 0; + printf("\nResetting to normal mode\n"); + }else{ + printf("\n\nPulsing Chip.\n");//really just toggles the enable + printf("Vcmp should be set to 2.0 and Vtrim should be 2.\n"); + } + + + Feb_Control_SetInTestModeVariable(on); + Feb_Control_SetStaticBits(); //toggle the enable 2x times + Feb_Control_ResetChipCompletely(); + + for(i=0;i memory address --> memory + data_in( 1..0) -> lsb + + mem_data_out(13.. 0) -> base + mem_data_out(17..14) -> slope + + delta = slope*lsb + corr = base+delta + */ + + int next_i=0; + b0[0] = 0; + m[0] = 1; + + for(i=0; i<1024; i++) + Feb_Control_rate_correction_table[i] = 65535; + + Feb_Control_rate_correction_table[0] = (((int)(m[0]+0.5)&0xf)<<14) | ((int)(b0[0]+0.5)&0x3fff); + + int b=0; + for(b=1;b<1024;b++){ + if(m[b-1]<15){ + double s=0,sx=0,sy=0,sxx=0,sxy=0; + for(;;next_i++){ + if(next_i>=np){ + b=1024; + b0[b] = 16383; + m[b] = 15; + break; + } + + double x = Feb_Control_rate_meas[next_i] - b*4; + double y = next_i; + /*printf("Start Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " + "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", + x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]);*/ + + if(x < -0.5) continue; + if(x > 3.5) break; + s += 1; + sx += x; + sy += y; + sxx += x*x; + sxy += x*y; + /*printf("End Loop x: %f,\t y: %f,\t s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " + "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", + x, y, s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]);*/ + } + double delta = s*sxx - sx*sx; + b0[b] = (sxx*sy - sx*sxy)/delta; + m[b] = (s*sxy - sx*sy) /delta; + + if(m[b]<0||m[b]>15){ + m[b]=15; + b0[b]=16383; + } + /*printf("After Loop s: %f,\t sx: %f,\t sy: %f,\t sxx: %f,\t sxy: %f,\t " + "next_i: %d,\t b: %d,\t Feb_Control_rate_meas[next_i]: %f\n", + s, sx, sy, sxx, sxy, next_i, b, Feb_Control_rate_meas[next_i]);*/ + // cout<>2] & 0x3fff; + slope = ((Feb_Control_rate_correction_table[i>>2] & 0x3c000) >> 14); + delta = slope*lsb; + corr = delta+base; + if(base==16383 && slope==15) corr=4095; + + printf("Readout Input: %d,\tBase:%d,\tSlope:%d,\tLSB:%d,\tDelta:%d\tResult:%d\tReal:%f\n", + i, base, slope, lsb, delta, corr, Feb_Control_rate_meas[i]); + } + return 1; +} + + +int Feb_Control_GetLeftFPGATemp(){ + unsigned int temperature=0; + Feb_Interface_ReadRegister(Module_GetTopLeftAddress (&modules[1]),FEB_REG_STATUS, &temperature); + temperature = temperature >> 16; + //division done in client to send int over network + return (int)temperature; +} + +int Feb_Control_GetRightFPGATemp(){ + unsigned int temperature=0; + Feb_Interface_ReadRegister(Module_GetTopRightAddress (&modules[1]),FEB_REG_STATUS, &temperature); + temperature = temperature >> 16; + //division done in client to send int over network + return (int)temperature; +} + + + diff --git a/slsDetectorSoftware/eigerDetectorServer/FebControl.cxx b/slsDetectorSoftware/eigerDetectorServer/FebControl.cxx new file mode 100644 index 000000000..05239d1c2 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/FebControl.cxx @@ -0,0 +1,1297 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +#include "FebRegisterDefs.h" +#include "FebControl.h" + +using namespace std; + +//GetDAQStatusRegister(512,current_mode_bits_from_fpga)){ + +const unsigned int Module::ndacs = 16; +const string Module::dac_names[16] = {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"}; + + +Module::Module(unsigned int number, unsigned int address_top){ + module_number = number; + top_address_valid = 1; + top_left_address = 0x100 | (0xff & address_top); + top_right_address = 0x200 | (0xff & address_top); + bottom_address_valid = 0; + bottom_left_address = 0; + bottom_right_address = 0; + + high_voltage = -1; + top_dac = new int [ndacs]; + bottom_dac = new int [ndacs]; + for(unsigned int i=0;iGetModuleNumber()); + ReadSetUpFile(modules[i]->GetModuleNumber(),st); + } + + + return CheckSetup(); +} + + +bool FebControl::ReadSetUpFileToAddModules(string file_name){ + static ifstream infile; + static string line; + static char cmd_st[2000]; + static int value_i[3]; + + infile.open(file_name.c_str(),ios::in); + if(!infile.is_open()) return 0; + + cout<>cmd_st; + if(!strcmp("add_module",cmd_st)){ + if(!(iss>>value_i[0]>>value_i[1]>>value_i[2])){ + cout<<"Error adding module from "<>value_i[0]>>value_i[1])){ + cout<<"Error adding half module from "<TopAddressIsValid()){ + feb_list[nfebs++] = modules[i]->GetTopRightAddress(); + feb_list[nfebs++] = modules[i]->GetTopLeftAddress(); + } + if(modules[i]->BottomAddressIsValid()){ + feb_list[nfebs++] = modules[i]->GetBottomRightAddress(); + feb_list[nfebs++] = modules[i]->GetBottomLeftAddress(); + } + } + + FebInterface::SendCompleteList(nfebs,feb_list); + delete [] feb_list; + + cout<GetModuleNumber()<<" "; + if(modules[i]->TopAddressIsValid()) cout<GetTopBaseAddress()<<" (top) "<BottomAddressIsValid()) cout<GetBottomBaseAddress()<<" (bottom)"<GetModuleNumber()==module_number){ + module_index=i; + return 1; + } + } + + return 0; +} + +bool FebControl::CheckModuleAddresses(Module* m){ + bool found_t = 0; + bool found_b = 0; + for(unsigned int i=0;iTopAddressIsValid() && modules[i]->GetTopBaseAddress() && m->GetTopBaseAddress()==modules[i]->GetTopBaseAddress()) || + (m->TopAddressIsValid() && modules[i]->GetBottomBaseAddress() && m->GetTopBaseAddress()==modules[i]->GetBottomBaseAddress())) found_t=1; + if((m->BottomAddressIsValid() && modules[i]->GetTopBaseAddress() && m->GetBottomBaseAddress()==modules[i]->GetTopBaseAddress()) || + (m->BottomAddressIsValid() && modules[i]->GetBottomBaseAddress() && m->GetBottomBaseAddress()==modules[i]->GetBottomBaseAddress())) found_b=1; + } + + if(found_t) cout<<"\tWarning: top address "<< m->GetTopBaseAddress()<<" already used."<GetBottomBaseAddress()<<" already used."<TopAddressIsValid()&&m->BottomAddressIsValid()&&m->GetTopBaseAddress()==m->GetBottomBaseAddress(); + if(top_bottom_same) cout<<"\tWarning: top and bottom address are the same "<GetTopBaseAddress()<<"."<TopAddressIsValid()&&m->BottomAddressIsValid()){ + cout<<"\tAdding full module number "<GetModuleNumber()<<" with top and bottom base addresses: "<GetTopBaseAddress()<<" "<GetBottomBaseAddress()<TopAddressIsValid()){ + cout<<"\tAdding half module number "<GetModuleNumber()<<" with top base address: "<GetTopBaseAddress()<BottomAddressIsValid()){ + cout<<"\tAdding half module number "<GetModuleNumber()<<" with bottom base address: "<GetBottomBaseAddress()<>cmd_st; + + if(cmd_st[0]=='#'||!strcmp("add_module",cmd_st)||!strcmp("add_half_module",cmd_st)){ ;// cout<<"do nothing "<>value_i[0])) cout<<"Error reading iodelay from "<>value_f; + SetHighVoltage(module_num,value_f); + }else if(!strcmp("photon_energy",cmd_st)){ + iss>>value_f; + SetPhotonEnergy(value_f); + }else if(!strcmp("dynamic_range",cmd_st)){ + iss>>value_i[0]; + SetDynamicRange(value_i[0]); + }else if(!strcmp("readout_speed",cmd_st)){ + iss>>value_i[0]; + SetReadoutSpeed(value_i[0]); + }else if(!strcmp("readout_mode",cmd_st)){ + iss>>value_i[0]; + SetReadoutMode(value_i[0]); + }else{ + iss>>value_f; + if(module_num>0) sprintf(cmd_st,"mod%d::%s",module_num,cmd_st); + if(!SetDAC(cmd_st,value_f,1)) cout<<"error in string: "<GetTopIDelay(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s idelay top number "<GetBottomIDelay(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s idelay bottom number "<GetHighVoltage()<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s high voltage not set."<GetTopDACValue(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s top \""<GetBottomDACValue(j)<0){ + cout<<"Warning: module "<GetModuleNumber()<<"'s bottom \""<TopAddressIsValid()) n_half_modules++; + if(modules[i]->BottomAddressIsValid()) n_half_modules++; + } + + return n_half_modules; +} + +bool FebControl::SetPhotonEnergy(unsigned int full_energy_eV){ + photon_energy_eV = full_energy_eV; + cout<<"Setting photon energy to: "<3){ + cout<<"Error SetIDelay chip_pos "<TopAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetTopLeftAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetTopIDelay(chip_pos,ndelay_units); + else{ + for(unsigned int i=0;iSetTopIDelay(chip_pos,ndelay_units); + for(unsigned int i=0;iSetBottomIDelay(chip_pos,ndelay_units); + } + }else{ + cout<<"Error could not set idelay module number "<BottomAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetBottomLeftAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetBottomIDelay(chip_pos,ndelay_units); + else{ + for(unsigned int i=0;iSetTopIDelay(chip_pos,ndelay_units); + for(unsigned int i=0;iSetBottomIDelay(chip_pos,ndelay_units); + } + }else{ + cout<<"Error could not set idelay module number "<TopAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetTopRightAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetTopIDelay(chip_pos,ndelay_units); + else for(unsigned int i=0;iSetTopIDelay(chip_pos,ndelay_units); + }else{ + cout<<"Error could not set idelay module number "<BottomAddressIsValid()){ + if(SendIDelays(modules[module_index]->GetBottomRightAddress(),chip_pos%2==0,0xffffffff,ndelay_units)){ + if(module_index!=0) modules[module_index]->SetBottomIDelay(chip_pos,ndelay_units); + else for(unsigned int i=0;iSetBottomIDelay(chip_pos,ndelay_units); + }else{ + cout<<"Error could not set idelay module number "<0x3ff) ndelay_units=0x3ff; + // this is global + unsigned int delay_data_valid_nclks = 15 - ((ndelay_units&0x3c0)>>6); //data valid delay upto 15 clks + ndelay_units &= 0x3f; + + unsigned int set_left_delay_channels = chip_lr ? channels:0; + unsigned int set_right_delay_channels = chip_lr ? 0:channels; + + cout<<"\tSetting delays of "; + if(set_left_delay_channels!=0) cout<<"left chips of dst_num "<vmax) return 0; + digital = int(((value-vmin)/(vmax-vmin))*(nsteps-1) + 0.5); + return 1; +} + +float FebControl::DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax){ + return vmin+(vmax-vmin)*digital/(nsteps-1); +} + + +bool FebControl::SetHighVoltage(float value){ + return SetHighVoltage(0,value); +} + +bool FebControl::SetHighVoltage(unsigned int module_num,float value){ + unsigned int module_index=0; + if(!GetModuleIndex(module_num,module_index)||!modules[module_index]->TopAddressIsValid()){ + cout<<"Error could not set high voltage module number "<GetTopRightAddress(),value)) return 0; + + if(module_index!=0) modules[module_index]->SetHighVoltage(value); + else for(unsigned int i=0;iSetHighVoltage(value); + + cout<<"\tHigh voltage of dst "<GetTopRightAddress()<<" set to "<GetHighVoltage()<<"."<4095){ + cout<<"Waring: SetDac bad value, "<TopAddressIsValid()){ + if(!SendDACValue(modules[module_index]->GetTopRightAddress(),dac_ch,v)) return 0; + if(module_index!=0) modules[module_index]->SetTopDACValue(dac_ch,v); + else for(unsigned int i=0;iSetTopDACValue(dac_ch,v); + } + + if(bottom&&modules[module_index]->BottomAddressIsValid()){ + if(!SendDACValue(modules[module_index]->GetBottomRightAddress(),dac_ch,v)) return 0; + if(module_index!=0) modules[module_index]->SetBottomDACValue(dac_ch,v); + else for(unsigned int i=0;iSetBottomDACValue(dac_ch,v); + } + + return 1; +} + +bool FebControl::GetDAC(std::string s, int& ret_value, bool voltage_mv){ + + unsigned int module_index, dac_ch; + bool top, bottom; + if(!DecodeDACString(s,module_index,top,bottom,dac_ch)) return 0; + + ret_value = top ? modules[module_index]->GetTopDACValue(dac_ch) : modules[module_index]->GetBottomDACValue(dac_ch); + + if(voltage_mv) ret_value = DACToVoltage(ret_value,4096,0,2048); + + return 1; +} + + +bool FebControl::GetDACName(unsigned int dac_num, std::string &s){ + if(dac_num>=Module::ndacs){ + cout<<"Warning: FebControl::GetDACName index out of range, "<15){ + cout<<"Warning invalid ch for SetDAC."<>3)<<((7-i)*4);//upper + trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[row_set*16480+super_column_start_position_r+i])<<((7-i)*4);//low + trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[row_set*16480+super_column_start_position_r+i])>>3)<<((7-i)*4);//upper +/* + trimbits_to_load_l[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])<<((7-i)*4);//low + trimbits_to_load_l[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_l+i)])>>3)<<((7-i)*4);//upper + trimbits_to_load_r[offset+chip_sc] |= ( 0x7 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])<<((7-i)*4);//low + trimbits_to_load_r[offset+chip_sc+32] |= ((0x38 & trimbits[263679 - (row_set*16480+super_column_start_position_r+i)])>>3)<<((7-i)*4);//upper + */ + + } // end column loop i + } //end supercolumn loop sc + } //end row loop + +/* + if(!WriteMemory(modules[0]->GetTopLeftAddress(),0,0,1024,trimbits_to_load_r)||!WriteMemory(modules[0]->GetTopRightAddress(),0,0,1024,trimbits_to_load_l)||!StartDAQOnlyNWaitForFinish()){ + cout <<" some errror!"<< endl; + return 0; + } +*/ + if(!WriteMemory(modules[0]->GetTopLeftAddress(),0,0,1023,trimbits_to_load_r)||!WriteMemory(modules[0]->GetTopRightAddress(),0,0,1023,trimbits_to_load_l)||!StartDAQOnlyNWaitForFinish()){ + cout <<" some errror!"<< endl; + return 0; + } + + } //end row_set loop (groups of 16 rows) + } // end l_r loop + memcpy(last_downloaded_trimbits,trimbits,trimbit_size*sizeof(unsigned char)); + return SetStaticBits(); //send the static bits +} + + +unsigned int* FebControl::GetTrimbits(){ + return last_downloaded_trimbits; +} + + + + +unsigned int FebControl::AddressToAll(){ + if(modules.size()==0) return 0; + return modules[0]->GetTopLeftAddress()|modules[0]->GetTopRightAddress(); +} + +bool FebControl::SetCommandRegister(unsigned int cmd){ + return WriteRegister(AddressToAll(),DAQ_REG_CHIP_CMDS,cmd); +} + + +bool FebControl::GetDAQStatusRegister(unsigned int dst_address, unsigned int &ret_status){ + + if(!ReadRegister(dst_address,DAQ_REG_STATUS,ret_status)){ + cout<<"Error: reading status register."<> 16; + return 1; +} + + +bool FebControl::StartDAQOnlyNWaitForFinish(int sleep_time_us){ + if(!WriteRegister(AddressToAll(),DAQ_REG_CTRL,0)||!WriteRegister(AddressToAll(),DAQ_REG_CTRL,DAQ_CTRL_START)){ + cout<<"Warning: could not start."<GetTopRightAddress(),status_reg_r))) + return 0; + if(status_reg_r&DAQ_STATUS_DAQ_RUNNING) return 1; + + /* + if(!(GetDAQStatusRegister(modules[i]->GetTopLeftAddress(),status_reg_r)&&GetDAQStatusRegister(modules[i]->GetTopRightAddress(),status_reg_l))){ + for(int i=0;i<2;i++) cout<<"Waring trouble reading status register. Returning zero to avoid inifite loops, this could cause trouble!"<full,1->half,2->quarter or 3->super_slow + acquireNReadoutMode &= (~DAQ_CHIP_CONTROLLER_SUPER_SLOW_SPEED); + if(readout_speed==1){ + acquireNReadoutMode |= DAQ_CHIP_CONTROLLER_HALF_SPEED; + cout<<"Everything at half speed, ie. reading with 50 MHz main clk (half speed) ...."<parallel,1->non-parallel,2-> safe_mode + acquireNReadoutMode &= (~DAQ_NEXPOSURERS_PARALLEL_MODE); + if(readout_mode==1){ + acquireNReadoutMode |= DAQ_NEXPOSURERS_NORMAL_NONPARALLEL_MODE; + cout<<"Readout mode set to normal non-parallel readout mode ... "< internal exposure time and period, + //"01"-> external acquistion start and internal exposure time and period, + //"10"-> external start trigger and internal exposure time, + //"11"-> external triggered start and stop of exposures + triggerMode = (~DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP); + + if(trigger_mode == 1){ + triggerMode = DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START; + cout<<"Trigger mode: external start of acquisition sequence, internal exposure length and period."<(pow(2,29)-1)*pow(10,7)){ + float max_time = 10e-9*(pow(2,28)-1)*pow(10,7); + cout<<"Warning: time exceeds ("<pow(2,29)-1){ power_of_ten++; n_clk_cycles = round(n_clk_cycles/10.0);} + decoded_time = int(n_clk_cycles)<<3 | int(power_of_ten); + } + + return decoded_time; +} + +bool FebControl::ResetChipCompletely(){ + if(!SetCommandRegister(DAQ_RESET_COMPLETELY) || !StartDAQOnlyNWaitForFinish()){ + cout<<"Warning: could not ResetChipCompletely()."<h_addr,(char *)&serv_addr.sin_addr.s_addr,server->h_length); + serv_addr.sin_port = htons(port); + + return 1; +} + +int FebControl::WriteNRead(char* message, int length, int max_length){ + + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + if(sockfd <0){ + fprintf(stderr,"ERROR opening socket\n"); + return 0; + } + + if(connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){ + fprintf(stderr,"ERROR connecting\n"); + return 0; + } + + int n = write(sockfd,message,length); + if(n<0) printf("ERROR writing to socket"); + + length = read(sockfd,message,max_length); + if(length<0) printf("ERROR reading to socket"); + + close(sockfd); + + return length; +} + + +bool FebControl::StartAcquisition(){ + + static unsigned int reg_nums[20]; + static unsigned int reg_vals[20]; + + PrintAcquisitionSetup(); + + // if(!Reset()||!ResetDataStream()){ + if(!Reset()){ + cout<<"Trouble reseting daq or data stream..."< +#include +//#include +//#include + + +#include "FebInterface.h" + + +struct Module{ + unsigned int module_number; + int top_address_valid; + unsigned int top_left_address; + unsigned int top_right_address; + int bottom_address_valid; + unsigned int bottom_left_address; + unsigned int bottom_right_address; + + unsigned int idelay_top[4]; //ll,lr,rl,ll + unsigned int idelay_bottom[4]; //ll,lr,rl,ll + float high_voltage; + int* top_dac; + int* bottom_dac; +}; + + +void Module_Module(struct Module* mod,unsigned int number, unsigned int address_top); +void Module_ModuleBottom(struct Module* mod,unsigned int number, unsigned int address_bottom); +void Module_Module1(struct Module* mod,unsigned int number, unsigned int address_top, unsigned int address_bottom); +unsigned int Module_GetModuleNumber(struct Module* mod); +int Module_TopAddressIsValid(struct Module* mod); +unsigned int Module_GetTopBaseAddress(struct Module* mod); +unsigned int Module_GetTopLeftAddress(struct Module* mod) ; +unsigned int Module_GetTopRightAddress(struct Module* mod); +unsigned int Module_GetBottomBaseAddress(struct Module* mod); +int Module_BottomAddressIsValid(struct Module* mod); +unsigned int Module_GetBottomLeftAddress(struct Module* mod); +unsigned int Module_GetBottomRightAddress(struct Module* mod); +unsigned int Module_SetTopIDelay(struct Module* mod,unsigned int chip,unsigned int value); +unsigned int Module_GetTopIDelay(struct Module* mod,unsigned int chip) ; +unsigned int Module_SetBottomIDelay(struct Module* mod,unsigned int chip,unsigned int value); +unsigned int Module_GetBottomIDelay(struct Module* mod,unsigned int chip); + +float Module_SetHighVoltage(struct Module* mod,float value); +float Module_GetHighVoltage(struct Module* mod); + +int Module_SetTopDACValue(struct Module* mod,unsigned int i, int value); +int Module_GetTopDACValue(struct Module* mod,unsigned int i); +int Module_SetBottomDACValue(struct Module* mod,unsigned int i, int value); +int Module_GetBottomDACValue(struct Module* mod,unsigned int i); + + + + + + +void Feb_Control_activate(int activate); + +int Feb_Control_IsBottomModule(); +int Feb_Control_GetModuleNumber(); + + + + + void Feb_Control_PrintModuleList(); + int Feb_Control_GetModuleIndex(unsigned int module_number, unsigned int* module_index); + int Feb_Control_CheckModuleAddresses(struct Module* m); + int Feb_Control_AddModule(unsigned int module_number, unsigned int top_address); + /*int Feb_Control_AddModule(unsigned int module_number, unsigned int top_address, unsigned int bottom_address, int half_module=0);*/ + int Feb_Control_AddModule1(unsigned int module_number, int top_enable, unsigned int top_address, unsigned int bottom_address, int half_module); + + int Feb_Control_GetDACNumber(char* s, unsigned int* n); + int Feb_Control_SendDACValue(unsigned int dst_num, unsigned int ch, unsigned int* value); + int Feb_Control_VoltageToDAC(float value, unsigned int* digital, unsigned int nsteps, float vmin, float vmax); + float Feb_Control_DACToVoltage(unsigned int digital,unsigned int nsteps,float vmin,float vmax); + + int Feb_Control_SendHighVoltage(unsigned int module_index, float* value); + + int Feb_Control_SendIDelays(unsigned int dst_num, int chip_lr, unsigned int channels, unsigned int ndelay_units); + + int Feb_Control_SetStaticBits(); + int Feb_Control_SetStaticBits1(unsigned int the_static_bits); + + int Feb_Control_SendBitModeToBebServer(); + + unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec); + + unsigned int Feb_Control_AddressToAll(); + int Feb_Control_SetCommandRegister(unsigned int cmd); + int Feb_Control_GetDAQStatusRegister(unsigned int dst_address, unsigned int* ret_status); + /*int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us=5000);*/ + int Feb_Control_StartDAQOnlyNWaitForFinish(int sleep_time_us); + + int Feb_Control_ResetChipCompletely(); + int Feb_Control_ResetChipPartially(); + + //struct sockaddr_in Feb_Control_serv_addr; + /* + int Feb_Control_SetupSendToSocket(const char* ip_address_hostname, unsigned short int port); + int Feb_Control_WriteNRead(char* message, int length, int max_length); +*/ + + + void Feb_Control_FebControl(); + int Feb_Control_Init(int master, int top, int module_num); + int Feb_Control_CheckSetup(); + + unsigned int Feb_Control_GetNModules(); + unsigned int Feb_Control_GetNHalfModules(); + + int Feb_Control_SetHighVoltage(float value); + int Feb_Control_SetHighVoltage1(unsigned int module_num,float value); + + + int Feb_Control_SetIDelays(unsigned int module_num, unsigned int ndelay_units); + int Feb_Control_SetIDelays1(unsigned int module_num, unsigned int chip_pos, unsigned int ndelay_units); + + int Feb_Control_DecodeDACString(char* dac_str, unsigned int* module_index, int* top, int* bottom, unsigned int* dac_ch); + /*int Feb_Control_SetDAC(string s, int value, int is_a_voltage_mv=0);*/ + int Feb_Control_SetDAC(char* s, int value, int is_a_voltage_mv); + /* int Feb_Control_GetDAC(string s, int* ret_value, int voltage_mv=0);*/ + int Feb_Control_GetDAC(char* s, int* ret_value, int voltage_mv); + int Feb_Control_GetDACName(unsigned int dac_num,char* s); + + int Feb_Control_SetTrimbits(unsigned int module_num, unsigned int* trimbits); + unsigned int* Feb_Control_GetTrimbits(); + + + /**Added by Dhanya */ + int Feb_Control_SaveAllTrimbitsTo(int value); + + + + int Feb_Control_Reset(); + int Feb_Control_PrepareForAcquisition(); + + int Feb_Control_StartAcquisition(); + int Feb_Control_StopAcquisition(); + int Feb_Control_AcquisitionInProgress(); + int Feb_Control_AcquisitionStartedBit(); + /*int Feb_Control_WaitForFinishedFlag(int sleep_time_us=5000);*/ + int Feb_Control_WaitForFinishedFlag(int sleep_time_us); + int Feb_Control_WaitForStartedFlag(int sleep_time_us, int prev_flag); + + //functions for setting up exposure + void Feb_Control_PrintAcquisitionSetup(); + int Feb_Control_SetNExposures(unsigned int n_images); + unsigned int Feb_Control_GetNExposures(); + int Feb_Control_SetExposureTime(double the_exposure_time_in_sec); + double Feb_Control_GetExposureTime(); + int Feb_Control_SetSubFrameExposureTime(int64_t the_subframe_exposure_time_in_10nsec); + int64_t Feb_Control_GetSubFrameExposureTime(); + int Feb_Control_SetExposurePeriod(double the_exposure_period_in_sec); + double Feb_Control_GetExposurePeriod(); + int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); + unsigned int Feb_Control_GetDynamicRange(); + int Feb_Control_SetReadoutSpeed(unsigned int readout_speed); //0 was default, 0->full,1->half,2->quarter or 3->super_slow + int Feb_Control_SetReadoutMode(unsigned int readout_mode); ///0 was default,0->parallel,1->non-parallel,2-> safe_mode + int Feb_Control_SetTriggerMode(unsigned int trigger_mode, int polarity);//0 and 1 was default, + int Feb_Control_SetExternalEnableMode(int use_external_enable, int polarity);//0 and 1 was default, + + //functions for testing + /*int Feb_Control_SetTestModeVariable(int on=1);*/ + int Feb_Control_SetInTestModeVariable(int on); + int Feb_Control_GetTestModeVariable(); + + void Feb_Control_Set_Counter_Bit(int value); + int Feb_Control_Get_Counter_Bit(); + int Feb_Control_Pulse_Pixel(int npulses,int x, int y); + int Feb_Control_PulsePixelNMove(int npulses, int inc_x_pos, int inc_y_pos); + int Feb_Control_Shift32InSerialIn(unsigned int value_to_shift_in); + int Feb_Control_SendTokenIn(); + int Feb_Control_ClockRowClock(unsigned int ntimes); + int Feb_Control_PulseChip(int npulses); + + int64_t Feb_Control_Get_RateTable_Tau_in_nsec(); + int64_t Feb_Control_Get_RateTable_Subexptime_in_nsec(); + int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec); + int Feb_Control_SetRateCorrectionTable(unsigned int *table); + int Feb_Control_GetRateCorrectionVariable(); + void Feb_Control_SetRateCorrectionVariable(int activate_rate_correction); + int Feb_Control_PrintCorrectedValues(); + + int Feb_Control_GetLeftFPGATemp(); + int Feb_Control_GetRightFPGATemp(); + +#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/FebInterface.c b/slsDetectorSoftware/eigerDetectorServer/FebInterface.c new file mode 100644 index 000000000..a094bda44 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/FebInterface.c @@ -0,0 +1,210 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + + +//#include +//#include +//#include +//#include +//#include +//#include + +#include +#include +#include + +#include "xparameters.h" + +#include "FebInterface.h" + + + + struct LocalLinkInterface ll_local,* ll; + + unsigned int Feb_Interface_nfebs; + unsigned int* Feb_Interface_feb_numb; + + int Feb_Interface_send_ndata; + unsigned int Feb_Interface_send_buffer_size; + unsigned int* Feb_Interface_send_data_raw; + unsigned int* Feb_Interface_send_data; + + int Feb_Interface_recv_ndata; + unsigned int Feb_Interface_recv_buffer_size; + unsigned int* Feb_Interface_recv_data_raw; + unsigned int* Feb_Interface_recv_data; + + +void Feb_Interface_FebInterface(){ + ll = &ll_local; + Feb_Interface_nfebs = 0; + Feb_Interface_feb_numb = 0; + + Feb_Interface_send_ndata = 0; + Feb_Interface_send_buffer_size = 1026; + Feb_Interface_send_data_raw = malloc((Feb_Interface_send_buffer_size+1) * sizeof(unsigned int)); + Feb_Interface_send_data = &Feb_Interface_send_data_raw[1]; + + Feb_Interface_recv_ndata = 0; + Feb_Interface_recv_buffer_size = 1026; + Feb_Interface_recv_data_raw = malloc((Feb_Interface_recv_buffer_size+1) * sizeof(unsigned int)); + Feb_Interface_recv_data = &Feb_Interface_recv_data_raw[1]; + + Local_LocalLinkInterface1(ll,XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); + +} + + + +void Feb_Interface_SendCompleteList(unsigned int n,unsigned int* list){ + unsigned int i; + if(Feb_Interface_feb_numb) free(Feb_Interface_feb_numb); + Feb_Interface_nfebs = n; + Feb_Interface_feb_numb = malloc(n * sizeof(unsigned int)); + for(i=0;i0xfff) return 0; + +#ifdef MARTIN + cprintf(YELLOW, "FIW ch %d\n", ch); +#endif + + Feb_Interface_send_data_raw[0] = 0x8fff0000; + if(Local_Write(ll,4,Feb_Interface_send_data_raw)!=4) return 0; + + Feb_Interface_send_data_raw[0] = 0x90000000 | (ch<<16); + if(Local_Write(ll,4,Feb_Interface_send_data_raw)!=4) return 0; + + Feb_Interface_send_data_raw[0] = 0xc0000000; + return ((Feb_Interface_send_ndata+1)*4==Local_Write(ll,(Feb_Interface_send_ndata+1)*4,Feb_Interface_send_data_raw)); +} + +int Feb_Interface_ReadFrom(unsigned int ch, unsigned int ntrys){ + unsigned int t; + if(ch>=0xfff) return 0; + + Feb_Interface_recv_data_raw[0] = 0xa0000000 | (ch<<16); + Local_Write(ll,4,Feb_Interface_recv_data_raw); + usleep(20); + + Feb_Interface_recv_ndata=-1; + for(t=0;t0){ + Feb_Interface_recv_ndata--; + break; + } + usleep(1000); + } + + return (Feb_Interface_recv_ndata>=0); +} + + + +int Feb_Interface_SetByteOrder(){ + Feb_Interface_send_data_raw[0] = 0x8fff0000; + if(Local_Write(ll,4,Feb_Interface_send_data_raw)!=4) return 0; + Feb_Interface_send_ndata = 2; + Feb_Interface_send_data[0] = 0; + Feb_Interface_send_data[1] = 0; + unsigned int i; + unsigned int dst = 0xff; + for(i=0;iFeb_Interface_send_buffer_size-2) return 0; + + Feb_Interface_send_ndata = nreads+2; + Feb_Interface_send_data[0] = 0x20000000 | nreads << 14; + + for(i=0;iFeb_Interface_send_buffer_size-2) return 0; + + //cout<<"Write register : "<0){ + n_to_send = ndata_countdownFeb_Interface_send_buffer_size-2) {printf("error herer: nwrites:%d\n",nwrites);return 0;}//*d-1026 + + Feb_Interface_send_ndata = nwrites+2;//*d-1026 + Feb_Interface_send_data[0] = 0xc0000000 | mem_num << 24 | nwrites << 14 | start_address; //cmd -> write to memory, nwrites, mem number, start address + Feb_Interface_send_data[nwrites+1] = 0; + for(i=0;i +#include +//#include +//#include +//#include +//#include + +#include "xparameters.h" + +#include "FebInterface.h" + +using namespace std; + +FebInterface::FebInterface(){ + + nfebs = 0; + feb_numb = 0; + + send_ndata = 0; + send_buffer_size = 1026; + send_data_raw = new unsigned int [send_buffer_size+1]; + send_data = &send_data_raw[1]; + + recv_ndata = 0; + recv_buffer_size = 1026; + recv_data_raw = new unsigned int [recv_buffer_size+1]; + recv_data = &recv_data_raw[1]; + + ll = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); + +} + +FebInterface::~FebInterface(){ + delete ll; + if(feb_numb) delete [] feb_numb; + delete [] send_data_raw; + delete [] recv_data_raw; +} + +void FebInterface::SendCompleteList(unsigned int n,unsigned int* list){ + if(feb_numb) delete [] feb_numb; + nfebs = n; + feb_numb = new unsigned int [n]; + for(unsigned int i=0;i0xfff) return 0; + + send_data_raw[0] = 0x8fff0000; + if(ll->Write(4,send_data_raw)!=4) return 0; + + send_data_raw[0] = 0x90000000 | (ch<<16); + if(ll->Write(4,send_data_raw)!=4) return 0; + + send_data_raw[0] = 0xc0000000; + return ((send_ndata+1)*4==ll->Write((send_ndata+1)*4,send_data_raw)); +} + +bool FebInterface::ReadFrom(unsigned int ch, unsigned int ntrys){ + if(ch>=0xfff) return 0; + + recv_data_raw[0] = 0xa0000000 | (ch<<16); + ll->Write(4,recv_data_raw); + usleep(20); + + recv_ndata=-1; + for(unsigned int t=0;tRead(recv_buffer_size*4,recv_data_raw)/4)>0){ + recv_ndata--; + break; + } + usleep(1000); + } + + return (recv_ndata>=0); +} + + + +bool FebInterface::SetByteOrder(){ + + send_data_raw[0] = 0x8fff0000; + if(ll->Write(4,send_data_raw)!=4) return 0; + + send_ndata = 2; + send_data[0] = 0; + send_data[1] = 0; + + unsigned int dst = 0xff; + for(unsigned int i=0;isend_buffer_size-2) return 0; + + send_ndata = nreads+2; + send_data[0] = 0x20000000 | nreads << 14; + + for(unsigned int i=0;isend_buffer_size-2) return 0; + + //cout<<"Write register : "<send_buffer_size-2) {cout<<"error herer: nwrites:"< write to memory, nwrites, mem number, start address + send_data[nwrites+1] = 0; + for(unsigned int i=0;ireadout ->expose -> ..., with store is always closed +#define DAQ_NEXPOSURERS_PARALLEL_MODE 0x00600000 //parallel acquire/read mode + +//DAQ_NEXPOSURERS_READOUT_COMPLETE_IMAGES is old now hard-wired in the firmware that every image comes with a header +//#define DAQ_NEXPOSURERS_READOUT_COMPLETE_IMAGES 0x00800000 //DAQ_IGNORE_INITIAL_CRAP and DAQ_CLKOUT_LAST_4_BITS_AND_RETURN_TO_START + +#define DAQ_NEXPOSURERS_EXTERNAL_ENABLING 0x01000000 +#define DAQ_NEXPOSURERS_EXTERNAL_ENABLING_POLARITY 0x02000000 +#define DAQ_NEXPOSURERS_EXTERNAL_TRIGGER_POLARITY 0x04000000 + +#define DAQ_NEXPOSURERS_INTERNAL_ACQUISITION 0x00000000 //internally controlled +#define DAQ_NEXPOSURERS_EXTERNAL_ACQUISITION_START 0x08000000 //external acquisition start +#define DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START 0x10000000 //external image start +#define DAQ_NEXPOSURERS_EXTERNAL_IMAGE_START_AND_STOP 0x18000000 //externally controlly, external image start and stop + +#define DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING 0x20000000 +#define DAQ_NEXPOSURERS_ACTIVATE_RATE_CORRECTION 0x40000000 + +//#define DAQ_MASTER_HALF_MODULE 0x80000000 currently not used + + +//chips static bits +#define DAQ_STATIC_BIT_PROGRAM 0x00000001 +#define DAQ_STATIC_BIT_M4 0x00000002 //these are the status bits, not bit mode +#define DAQ_STATIC_BIT_M8 0x00000004 //these are the status bits, not bit mode +#define DAQ_STATIC_BIT_M12 0x00000000 //these are the status bits, not bit mode, ie. "00" is 12 bit mode +#define DAQ_STATIC_BIT_CHIP_TEST 0x00000008 +#define DAQ_STATIC_BIT_ROTEST 0x00000010 +#define DAQ_CS_BAR_LEFT 0x00000020 +#define DAQ_CS_BAR_RIGHT 0x00000040 + + +//status flags +#define DAQ_STATUS_DAQ_RUNNING 0x01 +#define DAQ_DATA_COLLISION_ERROR 0x02 + + +#define DAQ_STATUS_CURRENT_M4 0x04 +#define DAQ_STATUS_CURRENT_M8 0x08 +#define DAQ_STATUS_CURRENT_M12 0x00 //in 12 bit mode both are cleared +#define DAQ_STATUS_CURRENT_TESTMODE 0x10 +#define DAQ_STATUS_TOKEN_OUT 0x20 +#define DAQ_STATUS_SERIAL_OUT 0x40 +#define DAQ_STATUS_PIXELS_ARE_ENABLED 0x80 +#define DAQ_STATUS_DAQ_RUN_TOGGLE 0x200 + +//data delay registers +#define CHIP_DATA_OUT_DELAY_REG_CTRL 1 +#define CHIP_DATA_OUT_DELAY_REG2 2 +#define CHIP_DATA_OUT_DELAY_REG3 3 +#define CHIP_DATA_OUT_DELAY_REG4 4 +#define CHIP_DATA_OUT_DELAY_SET 0x20000000 + +//module configuration +#define TOP_BIT_MASK 0x00f +#define MASTER_BIT_MASK 0x200 +// Master Slave Top Bottom Definition +#define MODULE_CONFIGURATION_MASK 0x84 +//Software Configuration +#define MASTERCONFIG_OFFSET 0x160 //0x20 * 11 (P11) +#define MASTER_BIT 0x1 +#define OVERWRITE_HARDWARE_BIT 0x2 +#define DEACTIVATE_BIT 0x4 + +#define FPGA_TEMP_OFFSET 0x200 + +#define TXM_DELAY_LEFT_OFFSET 0x180 +#define TXM_DELAY_RIGHT_OFFSET 0x1A0 +#define TXM_DELAY_FRAME_OFFSET 0x1C0 +#define TXM_FLOW_CONTROL_10G 0x140 + +//command memory +#define LEFT_OFFSET 0x0 +#define RIGHT_OFFSET 0x100 + +#define FIRST_CMD_PART1_OFFSET 0x8 +#define FIRST_CMD_PART2_OFFSET 0xc +#define SECOND_CMD_PART1_OFFSET 0x10 +#define SECOND_CMD_PART2_OFFSET 0x14 +#define COMMAND_COUNTER_OFFSET 0x18 +#define STOP_ACQ_OFFSET 0x1c +#define STOP_ACQ_BIT 0x40000000 +#define TWO_REQUESTS_OFFSET 0x1c +#define TWO_REQUESTS_BIT 0x80000000 + +//version +#define FIRMWARE_VERSION_OFFSET 0x4 +#define FIRMWARESOFTWARE_API_OFFSET 0x0 + +#define FRAME_NUM_RESET_OFFSET 0xA0 + +//temp so far +#define FEB_REG_STATUS 0xa + diff --git a/slsDetectorSoftware/eigerDetectorServer/FebServer.cxx b/slsDetectorSoftware/eigerDetectorServer/FebServer.cxx new file mode 100755 index 000000000..f86fc65aa --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/FebServer.cxx @@ -0,0 +1,604 @@ + +/** + * @author Ian Johnson + * @version 1.0 + * @developed for running Eiger at cSAXS + */ + + +#include +#include +#include +#include +#include // std::remove_if + +#include +#include +#include +#include +#include + +#include "FebControl.h" +#include "slsDetectorServer_defs.h" //include port number + +using namespace std; + +enum cmd_string {evNotFound, + evReinitialize,evReset, + + evSetInputDelays, + evSetDACValue,evGetDACValue,evSetDACVoltage,evGetDACVoltage,evSetHighVoltage,//evGetHighVoltage, + + evSetTrimBits, + evSetAllTrimBits, + evGetTrimBits, + //evLoadTrimBitFile, + + evSetBitMode, + evSetPhotonEnergy, + // evSetPhotonEnergyCalibrationParameters,evActivateRateCorrection,evDeactivateRateCorrection,evSetRateCorrectionTau, + + evSetReadoutSpeed,evSetReadoutMode, + + //temp solution + // evNotFound1,evNotFound2,evNotFound3, + + evSetNumberOfExposures,evSetExposureTime,evSetExposurePeriod, + // evSetTriggerPolarityToPositive,evSetTriggerPolarityToNegative, + evSetTriggerMode, + evSetExternalGating, + evStartAcquisition,evStopAcquisition,evIsDaqStillRunning, + evWaitUntilDaqFinished, + evExitServer +}; + +map enum_map; + +void init(){ + + enum_map["reinitialize"] = evReinitialize; + enum_map["reset"] = evReset; + enum_map["setinputdelays"] = evSetInputDelays; + enum_map["setdacvalue"] = evSetDACValue; + enum_map["getdacvalue"] = evGetDACValue; + enum_map["setdacvoltage"] = evSetDACVoltage; + enum_map["getdacvoltage"] = evGetDACVoltage; + enum_map["sethighvoltage"] = evSetHighVoltage; + enum_map["settrimbits"] = evSetTrimBits; + enum_map["setalltrimbits"] = evSetAllTrimBits; + enum_map["gettrimbits"] = evGetTrimBits; + // enum_map["loadtrimbitfile"] = evLoadTrimBitFile; + enum_map["setbitmode"] = evSetBitMode; + enum_map["setphotonenergy"] = evSetPhotonEnergy; + // enum_map["setphotonenergycalibrationparameters"] = evSetPhotonEnergyCalibrationParameters; + // enum_map["activateratecorrection"] = evActivateRateCorrection; + // enum_map["deactivateratecorrection"] = evDeactivateRateCorrection; + // enum_map["setratecorrectiontau"] = evSetRateCorrectionTau; + enum_map["setreadoutspeed"] = evSetReadoutSpeed; + enum_map["setreadoutmode"] = evSetReadoutMode; + enum_map["setnumberofexposures"] = evSetNumberOfExposures; + enum_map["setexposuretime"] = evSetExposureTime; + enum_map["setexposureperiod"] = evSetExposurePeriod; + // enum_map["settriggerpolaritytopositive"] = evSetTriggerPolarityToPositive; + // enum_map["settriggerpolaritytonegative"] = evSetTriggerPolarityToNegative; + enum_map["settriggermode"] = evSetTriggerMode; + enum_map["setexternalgating"] = evSetExternalGating; + enum_map["startacquisition"] = evStartAcquisition; + enum_map["stopacquisition"] = evStopAcquisition; + enum_map["isdaqstillrunning"] = evIsDaqStillRunning; + enum_map["waituntildaqfinished"] = evWaitUntilDaqFinished; + enum_map["exitserver"] = evExitServer; +} + +int server_list_s; +int server_conn_s; +int AccpetConnectionAndWaitForData(char* buffer, int maxlength); +bool WriteNClose(const char* buffer, int length); +bool SetupListenSocket(unsigned short int port); + + +string LowerCase(string str); +string GetNextString(string str,bool start_from_beginning=0); +void AddNumber(string& str, int n, int location=-1, bool space_after=0);//-1 means append +void AddNumber(string& str, float v, int location=-1, bool space_after=0);//-1 means append + +int main(int argc, char* argv[]){ + cout< "<0){ + int ret_parameter = 0; + return_start_pos = return_message.length(); + + switch(enum_map.find(LowerCase(cmd))->second){ + + case evReinitialize : + if(feb_controler->Init()){ + return_message.append("\tExecuted: Reinitialize\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: Reinitialize\n"); + ret_val = 1; + } + break; + + case evReset : + if(feb_controler->Reset()){ + return_message.append("\tExecuted: Reset\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: Reset\n"); + ret_val = 1; + } + break; + + + + case evSetInputDelays : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + + if(tmp_str[0].length()>0&&feb_controler->SetIDelays(0,n[0])){ + return_message.append("\tExecuted: SetInputDelays "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetInputDelays \n"); + ret_val = 1; + } + break; + + + + case evSetDACValue : + tmp_str[0] = GetNextString(data); + tmp_str[1] = GetNextString(data); + n[0] = atoi(tmp_str[1].data()); + + if(tmp_str[0].length()>0&&tmp_str[1].length()>0&&feb_controler->SetDAC(tmp_str[0],n[0])){ + return_message.append("\tExecuted: SetDACValue "); return_message.append(tmp_str[0]+" "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetDACValue \n"); + ret_val = 1; + } + break; + + case evGetDACValue : + tmp_str[0] = GetNextString(data); + + if(tmp_str[0].length()>0&&feb_controler->GetDAC(tmp_str[0],ret_parameter)){ + return_message.append("\tExecuted: GetDACValue "); return_message.append(tmp_str[0]+" -> ");AddNumber(return_message,ret_parameter); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: GetDACValue \n"); + ret_val = 1; + } + break; + + case evSetDACVoltage : + tmp_str[0] = GetNextString(data); + tmp_str[1] = GetNextString(data); + n[0] = atoi(tmp_str[1].data()); + + if(tmp_str[0].length()>0&&tmp_str[1].length()>0&&feb_controler->SetDAC(tmp_str[0],n[0],1)){ + return_message.append("\tExecuted: SetDACVoltage "); return_message.append(tmp_str[0]+" "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetDACVoltage \n"); + ret_val = 1; + } + break; + + case evGetDACVoltage : + tmp_str[0] = GetNextString(data); + + if(tmp_str[0].length()>0&&feb_controler->GetDAC(tmp_str[0],ret_parameter,1)){ + return_message.append("\tExecuted: GetDACVoltage "); return_message.append(tmp_str[0]+" -> ");AddNumber(return_message,ret_parameter); return_message.append(" mV\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: GetDACVoltage \n"); + ret_val = 1; + } + break; + + case evSetHighVoltage : + tmp_str[0] = GetNextString(data); + v[0] = atof(tmp_str[0].data()); + + if(tmp_str[0].length()>0&&feb_controler->SetHighVoltage(v[0])){ + return_message.append("\tExecuted: SetHighVoltage "); AddNumber(return_message,v[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetHighVoltage \n"); + ret_val = 1; + } + break; + + case evSetTrimBits : + tmp_str[0] = GetNextString(data); + if(feb_controler->LoadTrimbitFile()){ + /* if(1){*/ + /*tmp_str[0] = GetNextString(data); + feb_controler->SetTrimbits(0,(unsigned char*)(tmp_str[0].c_str()));*/ + return_message.append("\tExecuted: SetTrimBits\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetTrimBits \n"); + ret_val = 1; + } + break; + + case evSetAllTrimBits : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + if(feb_controler->SaveAllTrimbitsTo(n[0])){ + /*feb_controler->SetTrimbits(0,(unsigned char*)(tmp_str[0].c_str()));*/ + /*if(1){*/ + return_message.append("\tExecuted: SetAllTrimBits\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetAllTrimBits \n"); + ret_val = 1; + } + break; + + + case evGetTrimBits : + if(feb_controler->SaveTrimbitFile()){ + /*if(1){*/ + /*tmp_str[0] = GetNextString(data); + feb_controler->GetTrimbits();*/ + return_message.append("\tExecuted: GetTrimBits\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: GetTrimBits \n"); + ret_val = 1; + } + break; + + + // case evLoadTrimBitFile : + + case evSetBitMode : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + + if(tmp_str[0].length()>0&&feb_controler->SetDynamicRange(n[0])){ + return_message.append("\tExecuted: SetBitMode "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetBitMode \n"); + ret_val = 1; + } + break; + + case evSetPhotonEnergy : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + if(tmp_str[0].length()>0&&feb_controler->SetPhotonEnergy(n[0])){ + return_message.append("\tExecuted: SetPhotonEnergy "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetPhotonEnergy \n"); + ret_val = 1; + } + break; + + // case evSetPhotonEnergyCalibrationParameters : + // case evActivateRateCorrection : + // case evDeactivateRateCorrection : + // case evSetRateCorrectionTau : + + + case evSetReadoutSpeed : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + if(tmp_str[0].length()>0&&feb_controler->SetReadoutSpeed(n[0])){ + return_message.append("\tExecuted: SetReadoutSpeed "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetReadoutSpeed \n"); + ret_val = 1; + } + break; + + case evSetReadoutMode : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + if(tmp_str[0].length()>0&&feb_controler->SetReadoutMode(n[0])){ + return_message.append("\tExecuted: SetReadoutMode "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetReadoutMode parallel,1->non-parallel,2-> safe_mode>\n"); + ret_val = 1; + } + break; + + case evSetNumberOfExposures : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + if(tmp_str[0].length()>0&&feb_controler->SetNExposures(n[0])){ + return_message.append("\tExecuted: SetNumberOfExposures "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetNumberOfExposures \n"); + ret_val = 1; + } + break; + + case evSetExposureTime : + tmp_str[0] = GetNextString(data); + v[0] = atof(tmp_str[0].data()); + if(tmp_str[0].length()>0&&feb_controler->SetExposureTime(v[0])){ + return_message.append("\tExecuted: SetExposureTime "); AddNumber(return_message,v[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetExposureTime \n"); + ret_val = 1; + } + break; + + case evSetExposurePeriod : + tmp_str[0] = GetNextString(data); + v[0] = atof(tmp_str[0].data()); + if(tmp_str[0].length()>0&&feb_controler->SetExposurePeriod(v[0])){ + return_message.append("\tExecuted: SetExposurePeriod "); AddNumber(return_message,v[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetExposurePeriod \n"); + ret_val = 1; + } + break; + // case evSetTriggerPolarityToPositive : + // case evSetTriggerPolarityToNegative : + case evSetTriggerMode : + tmp_str[0] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + if(tmp_str[0].length()>0&&feb_controler->SetTriggerMode(n[0])){ + return_message.append("\tExecuted: SetTriggerMode "); AddNumber(return_message,n[0]); return_message.append("\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: SetTriggerMode \n"); + ret_val = 1; + } + break; + + case evSetExternalGating : + tmp_str[0] = GetNextString(data); + tmp_str[1] = GetNextString(data); + n[0] = atoi(tmp_str[0].data()); + n[1] = atoi(tmp_str[1].data()); + if(tmp_str[0].length()<1 || tmp_str[1].length()<1 || (n[0]!=0&&n[0]!=1) || (n[1]!=0&&n[1]!=1)){ + return_message.append("\tError executing: setexternalgating \n"); + ret_val = 1; + } + feb_controler->SetExternalEnableMode(n[0],n[1]); + ret_val = 0; + break; + + case evStartAcquisition : + if(feb_controler->StartAcquisition()){ + return_message.append("\tExecuted: StartAcquisition\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: StartAcquisition\n"); + ret_val = 1; + } + break; + + case evStopAcquisition : + if(feb_controler->StopAcquisition()){ + return_message.append("\tExecuted: StopAcquisition\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: StopAcquisition\n"); + ret_val = 1; + } + break; + + + case evIsDaqStillRunning : + return_message.append("\tExecuted: evIsDaqStillRunning\n"); + ret_parameter = feb_controler->AcquisitionInProgress(); + ret_val = 0; + break; + + + case evWaitUntilDaqFinished : + if(feb_controler->WaitForFinishedFlag()){ + return_message.append("\tExecuted: WaitUntilDaqFinished\n"); + ret_val = 0; + }else{ + return_message.append("\tError executing: WaitUntilDaqFinished\n"); + ret_val = 1; + } + break; + + + case evExitServer : + return_message.append("\tExiting Server ....\n"); + stop = 1; + ret_val = -200; + break; + + + default : + return_message.append("\tWarning command \""); + return_message.append(cmd); + return_message.append("\" not found.\n"); + return_message.append("\t\tValid commands: "); + map::iterator it = enum_map.begin(); + while(it!=enum_map.end()){ + return_message.append((it++)->first); + return_message.append(" "); + } + + ret_val=-100; + break; + } + + // return_message.append("\n"); + //AddNumber(return_message,ret_parameter,return_start_pos); + AddNumber(return_message,ret_val,return_start_pos,1); + AddNumber(return_message,ret_parameter,0,1); + if(ret_val!=0) break; + + cmd = GetNextString(data); + } + /*return_message.append("\n\n\n");*/ + + AddNumber(return_message,ret_val,0,1); + cout<0) return sub; + } + + return ""; +} + + +void AddNumber(string& str, int n, int location, bool space_after){ + static char retval_st[100]; + if(space_after) sprintf(retval_st,"%d ",n); + else sprintf(retval_st,"%d",n); + + if(location<0) str.append(retval_st); + else str.insert(location,retval_st); +} + +void AddNumber(string& str, float v, int location, bool space_after){ + static char retval_st[100]; + if(space_after) sprintf(retval_st,"%f ",v); + else sprintf(retval_st,"%f",v); + + if(location<0) str.append(retval_st); + else str.insert(location,retval_st); +} + + +bool SetupListenSocket(unsigned short int port){ + server_list_s=0; + server_conn_s=0; + + if((server_list_s = socket(AF_INET, SOCK_STREAM, 0))<0) return 0; + + struct sockaddr_in servaddr; /* socket address structure */ + memset(&servaddr, 0, sizeof(servaddr)); + servaddr.sin_family = AF_INET; + servaddr.sin_addr.s_addr = htonl(INADDR_ANY); + servaddr.sin_port = htons(port); + + if(bind(server_list_s,(struct sockaddr *) &servaddr,sizeof(servaddr))<0) return 0; + + if(listen(server_list_s,32) < 0){ // 1024 /* Backlog for listen() */ + return 0; + } + + return 1; +} + + +int AccpetConnectionAndWaitForData(char* buffer, int maxlength){ + if(server_list_s==0||maxlength<=0) return 0; + + if((server_conn_s = accept(server_list_s,NULL,NULL))< 0) return 0; + + int nread = read(server_conn_s,buffer,maxlength-1); + + if(nread<0) return 0; + + buffer[nread]='\0'; + return nread; +} + +bool WriteNClose(const char* buffer, int length){ + if(server_conn_s==0||length<=0) return 0; + + int nsent = write(server_conn_s,buffer,length); + if(close(server_conn_s)<0) return 0; + + server_conn_s=0; + return (nsent==length); +} + + + diff --git a/slsDetectorSoftware/eigerDetectorServer/HardwareIO.c b/slsDetectorSoftware/eigerDetectorServer/HardwareIO.c new file mode 100644 index 000000000..c8ca29fb7 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/HardwareIO.c @@ -0,0 +1,87 @@ + +//Class initially from Gerd and was called mmap_test.c +//return reversed 1 means good, 0 means failed + + +//#include +//#include +//#include +//#include +//#include + +#include "HardwareIO.h" + +xfs_u8 HWIO_xfs_in8(xfs_u32 InAddress) +{ + /* read the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + xfs_u8 IoContents; + __asm__ volatile ("eieio; lbz %0,0(%1)":"=r" (IoContents):"b" + (InAddress)); + return IoContents; +} + +/*****************************************************************************/ + +xfs_u16 HWIO_xfs_in16(xfs_u32 InAddress) +{ + /* read the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + xfs_u16 IoContents; + __asm__ volatile ("eieio; lhz %0,0(%1)":"=r" (IoContents):"b" + (InAddress)); + return IoContents; +} + +/*****************************************************************************/ + +xfs_u32 HWIO_xfs_in32(xfs_u32 InAddress) +{ + /* read the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + xfs_u32 IoContents; + __asm__ volatile ("eieio; lwz %0,0(%1)":"=r" (IoContents):"b" + (InAddress)); + return IoContents; +} + +/*****************************************************************************/ + +void HWIO_xfs_out8(xfs_u32 OutAddress, xfs_u8 Value) +{ + /* write the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + __asm__ volatile ("stb %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); +} + +/*****************************************************************************/ +void HWIO_xfs_out16(xfs_u32 OutAddress, xfs_u16 Value) +{ + /* write the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + __asm__ volatile ("sth %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); +} + +/*****************************************************************************/ + +void HWIO_xfs_out32(xfs_u32 OutAddress, xfs_u32 Value) +{ + /* write the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + __asm__ volatile ("stw %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); +} + + + diff --git a/slsDetectorSoftware/eigerDetectorServer/HardwareIO.cxx b/slsDetectorSoftware/eigerDetectorServer/HardwareIO.cxx new file mode 100644 index 000000000..3c6cff40b --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/HardwareIO.cxx @@ -0,0 +1,87 @@ + +//Class initially from Gerd and was called mmap_test.c +//return reversed 1 means good, 0 means failed + + +//#include +//#include +//#include +//#include +//#include + +#include "HardwareIO.h" + +xfs_u8 HardwareIO::xfs_in8(xfs_u32 InAddress) +{ + /* read the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + xfs_u8 IoContents; + __asm__ volatile ("eieio; lbz %0,0(%1)":"=r" (IoContents):"b" + (InAddress)); + return IoContents; +} + +/*****************************************************************************/ + +xfs_u16 HardwareIO::xfs_in16(xfs_u32 InAddress) +{ + /* read the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + xfs_u16 IoContents; + __asm__ volatile ("eieio; lhz %0,0(%1)":"=r" (IoContents):"b" + (InAddress)); + return IoContents; +} + +/*****************************************************************************/ + +xfs_u32 HardwareIO::xfs_in32(xfs_u32 InAddress) +{ + /* read the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + xfs_u32 IoContents; + __asm__ volatile ("eieio; lwz %0,0(%1)":"=r" (IoContents):"b" + (InAddress)); + return IoContents; +} + +/*****************************************************************************/ + +void HardwareIO::xfs_out8(xfs_u32 OutAddress, xfs_u8 Value) +{ + /* write the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + __asm__ volatile ("stb %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); +} + +/*****************************************************************************/ +void HardwareIO::xfs_out16(xfs_u32 OutAddress, xfs_u16 Value) +{ + /* write the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + __asm__ volatile ("sth %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); +} + +/*****************************************************************************/ + +void HardwareIO::xfs_out32(xfs_u32 OutAddress, xfs_u32 Value) +{ + /* write the contents of the I/O location and then synchronize the I/O + * such that the I/O operation completes before proceeding on + */ + + __asm__ volatile ("stw %0,0(%1); eieio"::"r" (Value), "b"(OutAddress)); +} + + + diff --git a/slsDetectorSoftware/eigerDetectorServer/HardwareIO.h b/slsDetectorSoftware/eigerDetectorServer/HardwareIO.h new file mode 100644 index 000000000..bc39d4668 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/HardwareIO.h @@ -0,0 +1,26 @@ + + +//Class initially from Gerd and was called mmap_test.c + +#ifndef HARDWAREIO_H +#define HARDWAREIO_H + +#include "xfs_types.h" + + + + xfs_u8 HWIO_xfs_in8(xfs_u32 InAddress); + xfs_u16 HWIO_xfs_in16(xfs_u32 InAddress); + xfs_u32 HWIO_xfs_in32(xfs_u32 InAddress); + + void HWIO_xfs_out8(xfs_u32 OutAddress, xfs_u8 Value); + void HWIO_xfs_out16(xfs_u32 OutAddress, xfs_u16 Value); + void HWIO_xfs_out32(xfs_u32 OutAddress, xfs_u32 Value); + + + + + + + +#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/HardwareMMappingDefs.h b/slsDetectorSoftware/eigerDetectorServer/HardwareMMappingDefs.h new file mode 100644 index 000000000..cdf63c122 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/HardwareMMappingDefs.h @@ -0,0 +1,62 @@ + + +//from Gerd and was called mmap_test.h + +#ifndef __PLB_LL_FIFO_H__ +#define __PLB_LL_FIFO_H__ + + +/******************************************************************************/ +/* definitions */ +/******************************************************************************/ + +#define PLB_LL_FIFO_REG_CTRL 0 +#define PLB_LL_FIFO_REG_STATUS 1 +#define PLB_LL_FIFO_REG_FIFO 2 + +#define PLB_LL_FIFO_CTRL_LL_REM_SHIFT 30 +#define PLB_LL_FIFO_CTRL_LL_REM 0xC0000000 +#define PLB_LL_FIFO_CTRL_LL_EOF 0x20000000 +#define PLB_LL_FIFO_CTRL_LL_SOF 0x10000000 +#define PLB_LL_FIFO_CTRL_LL_MASK 0xF0000000 + + +#define PLB_LL_FIFO_CTRL_TX_RESET 0x08000000 +#define PLB_LL_FIFO_CTRL_RX_RESET 0x04000000 + +#define PLB_LL_FIFO_CTRL_RESET_STATUS 0x00800000 +#define PLB_LL_FIFO_CTRL_RESET_USER 0x00400000 +#define PLB_LL_FIFO_CTRL_RESET_LINK 0x00200000 +#define PLB_LL_FIFO_CTRL_RESET_GT 0x00100000 + +#define PLB_LL_FIFO_CTRL_RESET_ALL 0x0CF00000 + +// do not reset complete gtx dual in std. case +// cause this would reset PLL and stop LL clk +#define PLB_LL_FIFO_CTRL_RESET_STD 0x0CE00000 + +// reset Rx and Tx Fifo and set User Reset +#define PLB_LL_FIFO_CTRL_RESET_FIFO 0x0C400000 + + +#define PLB_LL_FIFO_CTRL_CONFIG_VECTOR 0x000FFFFF + + +#define PLB_LL_FIFO_STATUS_LL_REM_SHIFT 30 +#define PLB_LL_FIFO_STATUS_LL_REM 0xC0000000 +#define PLB_LL_FIFO_STATUS_LL_EOF 0x20000000 +#define PLB_LL_FIFO_STATUS_LL_SOF 0x10000000 + +#define PLB_LL_FIFO_STATUS_EMPTY 0x08000000 +#define PLB_LL_FIFO_STATUS_ALMOSTEMPTY 0x04000000 +#define PLB_LL_FIFO_STATUS_FULL 0x02000000 +#define PLB_LL_FIFO_STATUS_ALMOSTFULL 0x01000000 + +#define PLB_LL_FIFO_STATUS_VECTOR 0x000FFFFF + +#define PLB_LL_FIFO_ALMOST_FULL_THRESHOLD_WORDS 100 + + +#endif // __PLB_LL_FIFO_H__ + + diff --git a/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.c b/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.c new file mode 100644 index 000000000..8d1b9db1f --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/LocalLinkInterface.c @@ -0,0 +1,260 @@ + +//Class initially from Gerd and was called mmap_test.c +//return reversed 1 means good, 0 means failed + + +#include +#include +//#include + + +#include "HardwareMMappingDefs.h" + +#include "LocalLinkInterface.h" + + + +void Local_LocalLinkInterface1(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr){ + // printf("\n v 1 \n"); + printf("Initialize PLB LL FIFOs\n"); + ll->ll_fifo_base=0; + ll->ll_fifo_ctrl_reg=0; + if(Local_Init(ll,ll_fifo_badr)){ + Local_Reset(ll); + printf("\tFIFO Status : 0x%08x\n",Local_StatusVector(ll)); + }else printf("\tError LocalLink Mappping : 0x%08x\n",ll_fifo_badr); + printf("\n\n"); +} + +/*~LocalLinkInterface(){};*/ + +void Local_LocalLinkInterface(struct LocalLinkInterface* ll){ + printf("Initializing new memory\n"); +} + + + +int Local_Init(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr){ + int fd; + void *plb_ll_fifo_ptr; + + if ((fd=open("/dev/mem", O_RDWR)) < 0){ + fprintf(stderr, "Could not open /dev/mem\n"); + return 0; + } + + plb_ll_fifo_ptr = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, ll_fifo_badr); + close(fd); + + if (plb_ll_fifo_ptr == MAP_FAILED){ + perror ("mmap"); + return 0; + } + + ll->ll_fifo_base = (xfs_u32) plb_ll_fifo_ptr; + ll->ll_fifo_ctrl_reg = 0; + + return 1; +} + + + +int Local_Reset(struct LocalLinkInterface* ll){ + return Local_Reset1(ll,PLB_LL_FIFO_CTRL_RESET_STD); +} + +int Local_Reset1(struct LocalLinkInterface* ll,unsigned int rst_mask){ + ll->ll_fifo_ctrl_reg |= rst_mask; + printf("\tCTRL Register bits: 0x%08x\n",ll->ll_fifo_ctrl_reg); + + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + + ll->ll_fifo_ctrl_reg &= (~rst_mask); + + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + // printf("FIFO CTRL Address: 0x%08x\n FIFO CTRL Register: 0x%08x\n",PLB_LL_FIFO_REG_CTRL,plb_ll_fifo[PLB_LL_FIFO_REG_CTRL]); + return 1; +} + + + +unsigned int Local_StatusVector(struct LocalLinkInterface* ll){ + return HWIO_xfs_in32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); +} + +int Local_Write(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer){ + // note: buffer must be word (4 byte) aligned + // frame_len in byte + int vacancy=0; + int i; + int words_send = 0; + int last_word; + unsigned int *word_ptr; + unsigned int fifo_ctrl; + xfs_u32 status; + + if (buffer_len < 1) return -1; + + last_word = (buffer_len-1)/4; + word_ptr = (unsigned int *)buffer; + +#ifdef MARTIN + cprintf(BLUE, "LL Write - Len: %2d - If: %X - Data: ",buffer_len, ll->ll_fifo_base); + for (i=0; i < buffer_len/4; i++) + cprintf(BLUE, "%.8X ",*(((unsigned *) buffer)+i)); + printf("\n"); +#endif + + while (words_send <= last_word) + { + while (!vacancy)//wait for Fifo to be empty again + { + status = HWIO_xfs_in32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); + if((status & PLB_LL_FIFO_STATUS_ALMOSTFULL) == 0) vacancy = 1; +#ifdef MARTIN + if (vacancy == 0) cprintf(RED, "Fifo full!\n"); +#endif + } + + //Just to know: #define PLB_LL_FIFO_ALMOST_FULL_THRESHOLD_WORDS 100 + for (i=0; ((ill_fifo_base+4*PLB_LL_FIFO_REG_FIFO,word_ptr[words_send++]); + } + } + return buffer_len; +} + + +int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer){ + static unsigned int buffer_ptr = 0; + // note: buffer must be word (4 byte) aligned + // frame_len in byte + int len; + unsigned int *word_ptr; + unsigned int status; + volatile unsigned int fifo_val; + int sof = 0; + +#ifdef MARTIN + cprintf(CYAN, "LL Read - If: %X - Data: ",ll->ll_fifo_base); +#endif + + word_ptr = (unsigned int *)buffer; + do + { + status = HWIO_xfs_in32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); + + if (!(status & PLB_LL_FIFO_STATUS_EMPTY)) + { + if (status & PLB_LL_FIFO_STATUS_LL_SOF) + { + if (buffer_ptr) + { + buffer_ptr = 0; + return -1; // buffer overflow + } + // printf(">>>> SOF\n\r"); + buffer_ptr = 0; + sof = 1; + } + + fifo_val = HWIO_xfs_in32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_FIFO); //read from fifo + + if ((buffer_ptr > 0) || sof) + { + if ( (buffer_len >> 2) > buffer_ptr) + { +#ifdef MARTIN + cprintf(CYAN, "%.8X ", fifo_val); +#endif + word_ptr[buffer_ptr++] = fifo_val; //write to buffer + } + else + { + buffer_ptr = 0; + return -2; // buffer overflow + } + + if (status & PLB_LL_FIFO_STATUS_LL_EOF) + { + len = (buffer_ptr << 2) -3 + ( (status & PLB_LL_FIFO_STATUS_LL_REM)>>PLB_LL_FIFO_STATUS_LL_REM_SHIFT ); +#ifdef MARTIN + cprintf(CYAN, "Len: %d\n",len); +#endif + // printf(">>>>status=0x%08x EOF len = %d \n\r\n\r",status, len); + buffer_ptr = 0; + return len; + } + + } + } + } + while(!(status & PLB_LL_FIFO_STATUS_EMPTY)); + + return 0; +} + +int Local_ctrl_reg_write_mask(struct LocalLinkInterface* ll,unsigned int mask, unsigned int val){ + // printf("Fifo CTRL Reg(1): 0x%08x\n",plb_ll_fifo_ctrl_reg); + ll->ll_fifo_ctrl_reg &= (~mask); + //printf("Fifo CTRL Reg(2): 0x%08x\n",plb_ll_fifo_ctrl_reg); + ll->ll_fifo_ctrl_reg |= ( mask & val); + // printf("Fifo CTRL Reg: 0x%08x\n",plb_ll_fifo_ctrl_reg); + HWIO_xfs_out32(ll->ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll->ll_fifo_ctrl_reg); + // printf("Fifo STAT Reg: 0x%08x\n", plb_ll_fifo[PLB_LL_FIFO_REG_STATUS]); + return 1; +} + + +int Local_Test(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer){ + + int len; + unsigned int rec_buff_len = 4096; + unsigned int rec_buffer[4097]; + + + Local_Write(ll,buffer_len,buffer); + usleep(10000); + + do{ + len = Local_Read(ll,rec_buff_len,rec_buffer); + printf("receive length: %i\n",len); + + if (len > 0){ + rec_buffer[len]=0; + printf((char*) rec_buffer); + printf("\n"); + } + } while(len > 0); + + printf("\n\n\n\n"); + return 1; +} + +void Local_llfifo_print_frame(struct LocalLinkInterface* ll,unsigned char* fbuff, int len){ + int i; + printf("\n\r----Frame of len : %d Byte\n\r",len); + for(i=0;i +#include +//#include + + +#include "HardwareMMappingDefs.h" + +#include "LocalLinkInterface.h" + + + +LocalLinkInterface::LocalLinkInterface(unsigned int ll_fifo_badr){ + // printf("\n v 1 \n"); + printf("Initialize PLB LL FIFOs\n"); + ll_fifo_base=0; + ll_fifo_ctrl_reg=0; + if(Init(ll_fifo_badr)){ + Reset(); + printf("\tFIFO Status : 0x%08x\n",StatusVector()); + }else printf("\tError LocalLink Mappping : 0x%08x\n",ll_fifo_badr); + + printf("\n\n"); +} + +LocalLinkInterface::~LocalLinkInterface(){}; + +LocalLinkInterface::LocalLinkInterface(){ + printf("Initialize new memory\n"); + } + +int LocalLinkInterface::InitNewMemory (unsigned int addr, int ifg){ + unsigned int CSP0BASE; + int fd; + + /*fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + printf("\nCan't find /dev/mem!\n"); + return 0; + } + printf("/dev/mem opened\n"); + + + CSP0BASE = (u_int32_t)mmap(0, 0x1000, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, addr); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + printf("\nCan't map memmory area!!\n"); + return 0; + } + printf("CSP0 mapped\n"); + + + volatile u_int8_t *ptr1; + + ptr1=(u_int8_t*)(CSP0BASE); + + printf("pointer val=%x\n",(void*)ptr1); + + printf("ifg_control=%02x\n",*ptr1); + + *ptr1=ifg; + + printf("ifg_control new=%02x\n",*ptr1); + + close(fd); +*/ + return 1; +} + + + +bool LocalLinkInterface::Init(unsigned int ll_fifo_badr){ + int fd; + void *plb_ll_fifo_ptr; + + if ((fd=open("/dev/mem", O_RDWR)) < 0){ + fprintf(stderr, "Could not open /dev/mem\n"); + return 0; + } + + plb_ll_fifo_ptr = mmap(0, getpagesize(), PROT_READ | PROT_WRITE, MAP_FILE | MAP_SHARED, fd, ll_fifo_badr); + close(fd); + + if (plb_ll_fifo_ptr == MAP_FAILED){ + perror ("mmap"); + return 0; + } + + ll_fifo_base = (xfs_u32) plb_ll_fifo_ptr; + ll_fifo_ctrl_reg = 0; + + return 1; +} + + + +bool LocalLinkInterface::Reset(){ + return Reset(PLB_LL_FIFO_CTRL_RESET_STD); +} + +bool LocalLinkInterface::Reset(unsigned int rst_mask){ + ll_fifo_ctrl_reg |= rst_mask; + printf("\tCTRL Register bits: 0x%08x\n",ll_fifo_ctrl_reg); + + xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); + xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); + xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); + xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); + + ll_fifo_ctrl_reg &= (~rst_mask); + + xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); + // printf("FIFO CTRL Address: 0x%08x\n FIFO CTRL Register: 0x%08x\n",PLB_LL_FIFO_REG_CTRL,plb_ll_fifo[PLB_LL_FIFO_REG_CTRL]); + return 1; +} + + + +unsigned int LocalLinkInterface::StatusVector(){ + return xfs_in32(ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); +} + +int LocalLinkInterface::Write(unsigned int buffer_len, void *buffer){ + // note: buffer must be word (4 byte) aligned + // frame_len in byte + int vacancy=0; + int i; + int words_send = 0; + int last_word; + unsigned int *word_ptr; + unsigned int fifo_ctrl; + xfs_u32 status; + + if (buffer_len < 1) return -1; + + last_word = (buffer_len-1)/4; + word_ptr = (unsigned int *)buffer; + + while (words_send <= last_word) + { + while (!vacancy)//wait for Fifo to be empty again + { + status = xfs_in32(ll_fifo_base+4*PLB_LL_FIFO_REG_STATUS); + if((status & PLB_LL_FIFO_STATUS_ALMOSTFULL) == 0) vacancy = 1; + } + + //Just to know: #define PLB_LL_FIFO_ALMOST_FULL_THRESHOLD_WORDS 100 + for (i=0; ((i>>> SOF\n\r"); + buffer_ptr = 0; + sof = 1; + } + + fifo_val = xfs_in32(ll_fifo_base+4*PLB_LL_FIFO_REG_FIFO); //read from fifo + + if ((buffer_ptr > 0) || sof) + { + if ( (buffer_len >> 2) > buffer_ptr) + { + word_ptr[buffer_ptr++] = fifo_val; //write to buffer + } + else + { + buffer_ptr = 0; + return -2; // buffer overflow + } + + if (status & PLB_LL_FIFO_STATUS_LL_EOF) + { + len = (buffer_ptr << 2) -3 + ( (status & PLB_LL_FIFO_STATUS_LL_REM)>>PLB_LL_FIFO_STATUS_LL_REM_SHIFT ); +// printf(">>>>status=0x%08x EOF len = %d \n\r\n\r",status, len); + buffer_ptr = 0; + return len; + } + + } + } + } + while(!(status & PLB_LL_FIFO_STATUS_EMPTY)); + + return 0; +} + +bool LocalLinkInterface::ctrl_reg_write_mask(unsigned int mask, unsigned int val){ + // printf("Fifo CTRL Reg(1): 0x%08x\n",plb_ll_fifo_ctrl_reg); + ll_fifo_ctrl_reg &= (~mask); + //printf("Fifo CTRL Reg(2): 0x%08x\n",plb_ll_fifo_ctrl_reg); + ll_fifo_ctrl_reg |= ( mask & val); +// printf("Fifo CTRL Reg: 0x%08x\n",plb_ll_fifo_ctrl_reg); + xfs_out32(ll_fifo_base+4*PLB_LL_FIFO_REG_CTRL,ll_fifo_ctrl_reg); +// printf("Fifo STAT Reg: 0x%08x\n", plb_ll_fifo[PLB_LL_FIFO_REG_STATUS]); + return 1; +} + + +int LocalLinkInterface::Test(unsigned int buffer_len, void *buffer){ + + int len; + unsigned int rec_buff_len = 4096; + unsigned int rec_buffer[4097]; + + + Write(buffer_len,buffer); + usleep(10000); + + do{ + len = Read(rec_buff_len,rec_buffer); + printf("receive length: %i\n",len); + + if (len > 0){ + rec_buffer[len]=0; + printf((char*) rec_buffer); + printf("\n"); + } + } while(len > 0); + + printf("\n\n\n\n"); + return 1; +} + +void LocalLinkInterface::llfifo_print_frame(unsigned char* fbuff, int len){ + printf("\n\r----Frame of len : %d Byte\n\r",len); + for(int i=0;i + +#include "ansi.h" +#include +#include + +/*class LocalLinkInterface: public HardwareIO{ //*/ + + +struct LocalLinkInterface{ + xfs_u32 ll_fifo_base; + unsigned int ll_fifo_ctrl_reg; +}; + + + + int Local_Init(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr); + int Local_Reset1(struct LocalLinkInterface* ll,unsigned int rst_mask); + + int Local_ctrl_reg_write_mask(struct LocalLinkInterface* ll,unsigned int mask, unsigned int val); + void Local_llfifo_print_frame(struct LocalLinkInterface* ll,unsigned char* fbuff, int len); + + + void Local_LocalLinkInterface1(struct LocalLinkInterface* ll,unsigned int ll_fifo_badr); + /* virtual ~LocalLinkInterface();*/ + + unsigned int Local_StatusVector(struct LocalLinkInterface* ll); + int Local_Reset(struct LocalLinkInterface* ll); + int Local_Write(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); + int Local_Read(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); + + int Local_Test(struct LocalLinkInterface* ll,unsigned int buffer_len, void *buffer); + + void Local_LocalLinkInterface(struct LocalLinkInterface* ll); + + /* + int FiFoReset(unsigned int numb); + int FifoSend(unsigned int numb, unsigned int frame_len, void *buffer); + int FifoReceive(unsigned int numb, unsigned int frame_len, void *buffer); + int FifoTest(unsigned int numb,unsigned int send_len, char *send_str); + */ + + + + +#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/LocalLinkTest.cxx b/slsDetectorSoftware/eigerDetectorServer/LocalLinkTest.cxx new file mode 100644 index 000000000..7934aff05 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/LocalLinkTest.cxx @@ -0,0 +1,28 @@ + +#include + +#include "xparameters.h" + +#include "LocalLinkInterface.h" + +int main(){ + + char s[2000]; + sprintf(s,"papamama"); + + LocalLinkInterface* l0 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR); + l0->Test(8,s); + LocalLinkInterface* l1 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_LEFT_BASEADDR); + l1->Test(8,s); + LocalLinkInterface* l2 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR); + l2->Test(8,s); + LocalLinkInterface* l3 = new LocalLinkInterface(XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_RIGHT_BASEADDR); + l3->Test(8,s); + + delete l0; + delete l1; + delete l2; + delete l3; + + return 1; +} diff --git a/slsDetectorSoftware/eigerDetectorServer/Makefile b/slsDetectorSoftware/eigerDetectorServer/Makefile new file mode 100755 index 000000000..462930bac --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Makefile @@ -0,0 +1,39 @@ +CC = powerpc-4xx-softfloat-gcc +CCX = powerpc-4xx-softfloat-g++ +CFLAGS += -Wall -DDACS_INT -DEIGERD -DSLS_DETECTOR_FUNCTION_LIST -DDACS_INT -DSTOP_SERVER #-DVERBOSE #-DVIRTUAL -DPCCOMPILE -DMARTIN +LDLIBS += -lm -lstdc++ + +PROGS = eigerDetectorServer +DESTDIR ?= bin +INSTMODE = 0777 + + +SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c FebControl.c Beb.c HardwareIO.c LocalLinkInterface.c Feb.c FebInterface.c +#SRC_CLNT2 = FebServer.cxx FebControl.cxx FebInterface.cxx LocalLinkInterface.cxx HardwareIO.cxx +#SRC_CLNT3 = BebServer.cxx Beb.cxx LocalLinkInterface.cxx HardwareIO.cxx + +OBJS = $(SRC_CLNT:.c=.o) + + +all: clean $(PROGS) #feb_debug beb_debug + + +boot: $(OBJS) + +$(PROGS): + echo $(OBJS) + mkdir -p $(DESTDIR) + $(CC) -o $@ $(SRC_CLNT) $(CFLAGS) $(LDLIBS) + mv $(PROGS) $(DESTDIR) + +feb_debug:$(SRC_CLNT2) + $(CCX) -o feb_debug $(SRC_CLNT2) -I. + mv feb_debug $(DESTDIR) + +beb_debug:$(SRC_CLNT3) + $(CCX) -o beb_debug $(SRC_CLNT3) -I. + mv beb_debug $(DESTDIR) + +clean: + rm -rf $(DESTDIR)/$(PROGS) *.o + diff --git a/slsDetectorSoftware/eigerDetectorServer/Makefile.virtual b/slsDetectorSoftware/eigerDetectorServer/Makefile.virtual new file mode 100644 index 000000000..9d3bc6223 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Makefile.virtual @@ -0,0 +1,28 @@ +CC = gcc +CFLAGS += -Wall -DDACS_INT -DEIGERD -DDACS_INT -DPCCOMPILE -DSLS_DETECTOR_FUNCTION_LIST #-DSTOP_SERVER #-DVERBOSE #-DVIRTUAL -DPCCOMPILE +LDLIBS += -lm -lstdc++ + +PROGS = eigerDetectorServerVirtual +DESTDIR ?= bin +INSTMODE = 0777 + +SRC_CLNT = communication_funcs.c slsDetectorServer.c slsDetectorServer_funcs.c slsDetectorFunctionList.c +#SRC_CLNT2 = Eiger.cxx HardwareIO.cxx LocalLinkInterface.cxx Feb.cxx +OBJS = $(SRC_CLNT:.c=.o) +OBJS2 = $(SRC_CLNT2:.cpp=.o) + + +all: clean $(PROGS) + + +boot: $(OBJS) $(OBJS2) + +$(PROGS): + echo $(OBJS) $(OBJS2) + mkdir -p $(DESTDIR) + $(CC) -o $@ $(SRC_CLNT) $(CFLAGS) $(LDLIBS) + mv $(PROGS) $(DESTDIR) + +clean: + rm -rf $(DESTDIR)/$(PROGS) *.o + \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/Test.cxx b/slsDetectorSoftware/eigerDetectorServer/Test.cxx new file mode 100644 index 000000000..8e07d609b --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/Test.cxx @@ -0,0 +1,38 @@ + +/** + * @author Ian Johnson + * @version 1.0 + */ + + +#include +#include + +#include "xparameters.h" + +#include "Feb.h" + + +using namespace std; + +int main(){ + + cout<<"\n\n\n\n\n\n\n\n\n\n"<ReadRegister(0,0,v); + feb->ReadRegister(0,0xffffffff,v); + cout<ReadRegister(1,0,v); + feb->ReadRegister(1,0xffffffff,v); + + delete feb; + + return 1; +} diff --git a/slsDetectorSoftware/eigerDetectorServer/ansi.h b/slsDetectorSoftware/eigerDetectorServer/ansi.h new file mode 120000 index 000000000..a122db0ad --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/ansi.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServerVirtual b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServerVirtual new file mode 100755 index 000000000..7a8d32b62 Binary files /dev/null and b/slsDetectorSoftware/eigerDetectorServer/bin/eigerDetectorServerVirtual differ diff --git a/slsDetectorSoftware/eigerDetectorServer/build.sh b/slsDetectorSoftware/eigerDetectorServer/build.sh new file mode 100755 index 000000000..876ac32f5 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/build.sh @@ -0,0 +1,19 @@ + +echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" + +. /opt/eldk-5.1/powerpc-4xx-softfloat/environment-setup-ppc440-linux + +#powerpc-4xx-softfloat-g++ -Wall -o test Test.cxx HardwareIO.cxx LocalLinkInterface.cxx Feb.cxx -I . +#powerpc-4xx-softfloat-g++ -Wall -o hardware_interface_test HardwareInterfaceTest.cxx HardwareInterface.cxx HardwareMMapping.cxx -I . + + +#powerpc-4xx-softfloat-g++ -Wall -o eiger_test EigerTest.cxx Eiger.cxx HardwareIO.cxx LocalLinkInterface.cxx Feb.cxx -I . + +powerpc-4xx-softfloat-g++ -Wall -o feb_debug FebServer.cxx FebControl.cxx FebInterface.cxx LocalLinkInterface.cxx HardwareIO.cxx -I . + +powerpc-4xx-softfloat-g++ -Wall -o beb_debug BebServer.cxx Beb.cxx LocalLinkInterface.cxx HardwareIO.cxx -I . + + +cp eiger_test rootfs_executables/. + + diff --git a/slsDetectorSoftware/eigerDetectorServer/communication_funcs.c b/slsDetectorSoftware/eigerDetectorServer/communication_funcs.c new file mode 120000 index 000000000..87a4f95d1 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/communication_funcs.c @@ -0,0 +1 @@ +../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/communication_funcs.h b/slsDetectorSoftware/eigerDetectorServer/communication_funcs.h new file mode 120000 index 000000000..f220903b2 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/communication_funcs.h @@ -0,0 +1 @@ +../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/doxy_eiger.config b/slsDetectorSoftware/eigerDetectorServer/doxy_eiger.config new file mode 100644 index 000000000..9f9de954a --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/doxy_eiger.config @@ -0,0 +1,94 @@ +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + + + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +INTERNAL_DOCS = NO + +SHOW_INCLUDE_FILES = NO + +SHOW_FILES = NO + +SHOW_NAMESPACES = NO + +COMPACT_LATEX = YES + +PAPER_TYPE = a4 + +PDF_HYPERLINKS = YES + +USE_PDFLATEX = YES + +LATEX_HIDE_INDICES = YES + +PREDEFINED = __cplusplus + +HAVE_DOT = YES +CALL_GRAPH = YES +CALLER_GRAPH = YES + + +INPUT = Beb.h Eiger.h FebControl.h FebInterface.h gitInfoEiger.h HardwareIO.h LocalLinkInterface.h sls_detector_funcs.h slsDetectorServer_defs.h sls_receiver_defs.h xfs_types.h communication_funcs.h EigerRegisterDefs.h Feb.h FebRegisterDefs.h gitInfoEigerTmp.h HardwareMMappingDefs.h sls_detector_defs.h slsDetectorFunctionList.h slsDetectorServer_funcs.h sls_receiver_funcs.h xparameters.h Beb.cxx BebServer.cxx Eiger.cxx EigerTest.cxx FebControl.cxx Feb.cxx FebInterface.cxx FebServer.cxx HardwareIO.cxx LocalLinkInterface.cxx LocalLinkTest.cxx Test.cxx + + + + +OUTPUT_DIRECTORY = docs + diff --git a/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt b/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt new file mode 100644 index 000000000..699f0201f --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/gitInfo.txt @@ -0,0 +1,9 @@ +Path: slsDetectorsPackage/slsDetectorSoftware/eigerDetectorServer +URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git/eigerDetectorServer +Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git +Repsitory UUID: 372aa91aaff8c6acd0fb70a257774ac56974a4b1 +Revision: 233 +Branch: 2.1-rc +Last Changed Author: Dhanya_Maliakal +Last Changed Rev: 22 +Last Changed Date: 2016-09-22 17:16:49 +0200 diff --git a/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h b/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h new file mode 100644 index 000000000..2f61cd1dc --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/gitInfoEiger.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "git@git.psi.ch:sls_detectors_software/sls_detector_software.git/eigerDetectorServer" +//#define SVNREPPATH "" +#define SVNREPUUID "372aa91aaff8c6acd0fb70a257774ac56974a4b1" +//#define SVNREV 0x22 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "Dhanya_Maliakal" +#define SVNREV 0x22 +#define SVNDATE 0x20160922 +// diff --git a/slsDetectorSoftware/eigerDetectorServer/gitInfoEigerTmp.h b/slsDetectorSoftware/eigerDetectorServer/gitInfoEigerTmp.h new file mode 100644 index 000000000..58e48f497 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/gitInfoEigerTmp.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "" +//#define SVNREPPATH "" +#define SVNREPUUID "" +//#define SVNREV "" +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "" +#define SVNREV "" +#define SVNDATE "" +// diff --git a/slsDetectorSoftware/eigerDetectorServer/renameServer.sh b/slsDetectorSoftware/eigerDetectorServer/renameServer.sh new file mode 100644 index 000000000..9aca06728 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/renameServer.sh @@ -0,0 +1,3 @@ +mv bin/eigerDetectorServer bin/$2 +git rm -f bin/$1 +git add bin/$2 diff --git a/slsDetectorSoftware/eigerDetectorServer/setup.txt b/slsDetectorSoftware/eigerDetectorServer/setup.txt new file mode 100644 index 000000000..64c3600e1 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/setup.txt @@ -0,0 +1,53 @@ + + +#detector setup + #add_module module_number base_address_top (for half module) + #add_module module_number base_address_top base_address_bottom (for full module) +add_half_module 17 0 +#add_half_module 17 1 for bottom +#add_module 18 10 12 +#add_module 2 13 15 +#add_module 1 120 22 + + +#default setting +photon_energy 8000 +dynamic_range 16 +readout_speed 1 #(0-full,1-half,2-quarter and 3-superslow) +readout_mode 0 #(0-parallel,1-non_parallel,2-safe_mode) + + +#default dacs +SvP 0 +Vtr 1280 +Vrf 1550 +Vrs 700 +SvN 2000 +Vtgstv 1278 +Vcmp_ll 750 +Vcmp_lr 750 +cal 2000 +Vcmp_rl 750 +rxb_rb 600 +rxb_lb 600 +Vcmp_rr 750 +Vcp 100 +Vcn 1000 +Vis 775 + +#default high_voltage +high_voltage 152 + +#default iodelays +iodelay 675 + +#newgoodiodelay 643 +#halfspeed_add_about 32 +#goodiodelay 1467 +#goodiodelay 1550 + + + + + + diff --git a/slsDetectorSoftware/eigerDetectorServer/setup_beb.txt b/slsDetectorSoftware/eigerDetectorServer/setup_beb.txt new file mode 100644 index 000000000..148cc17e9 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/setup_beb.txt @@ -0,0 +1,12 @@ + + +#detector setup +#add_beb base_address mac_1GBE ip_1GBE mac_10GBE ip_10GBE + +add_beb 26 0 00:50:c2:46:d9:34 129.129.205.78 00:50:c2:46:d9:35 10.0.26.1 + + + + + + diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c new file mode 100644 index 000000000..2ea8bab1c --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.c @@ -0,0 +1,1331 @@ +#ifdef SLS_DETECTOR_FUNCTION_LIST + + +#include +#include //to gethostname +#include + + + +#include "slsDetectorFunctionList.h" +#include "gitInfoEiger.h" +#include "FebControl.h" +#include "Beb.h" + +int default_tau_from_file= -1; + +#define BEB_NUM 34 + +enum detectorSettings thisSettings; +const char* dac_names[16] = {"SvP","Vtr","Vrf","Vrs","SvN","Vtgstv","Vcmp_ll","Vcmp_lr","cal","Vcmp_rl","rxb_rb","rxb_lb","Vcmp_rr","Vcp","Vcn","Vis"}; + +enum{E_PARALLEL, E_NON_PARALLEL, E_SAFE}; + +//static const string dacNames[16] = {"Svp","Svn","Vtr","Vrf","Vrs","Vtgstv","Vcmp_ll","Vcmp_lr","Cal","Vcmp_rl","Vcmp_rr","Rxb_rb","Rxb_lb","Vcp","Vcn","Vis"}; + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +dacs_t *detectorDacs=NULL; +dacs_t *detectorAdcs=NULL; +int* detectorGain = NULL; +int* detectorOffset = NULL; + +int eiger_highvoltage = 0; +int eiger_iodelay = 0; +int eiger_photonenergy = 0; +int eiger_dynamicrange = 0; +int eiger_readoutmode = 0; +int eiger_storeinmem = 0; +int eiger_readoutspeed = 0; +int eiger_triggermode = 0; +int eiger_extgating = 0; +int eiger_extgatingpolarity = 0; + + +int eiger_nexposures = 1; +int eiger_ncycles = 1; + + +int send_to_ten_gig = 0; +int ndsts_in_use=32; +unsigned int nimages_per_request=1; +int on_dst=0; +int dst_requested[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +int default_dac_values[16] = { + 0, //SvP + 2480, //Vtr + 3300, //Vrf + 1400, //Vrs + 4000, //SvN + 2556, //Vtgstv + 1000, //Vcmp_ll + 1000, //Vcmp_lr + 4000, //cal + 1000, //Vcmp_rl + 1100, //rxb_rb + 1100, //rxb_lb + 1000, //Vcmp_rr + 1000, //Vcp + 2000, //Vcn + 1550 //Vis +}; +int default_gain_values[3] = {517000,517000,517000}; +int default_offset_values[3] = {3851000,3851000,3851000}; + + +enum masterFlags masterMode=IS_SLAVE; +int top = 0; +int master = 0; + + +#define TEN_GIGA_BUFFER_SIZE 4112 +#define ONE_GIGA_BUFFER_SIZE 1040 + + +int initDetector(){ + int imod,i,n; + n = getNModBoard(1); + + //#ifdef VERBOSE + printf("This Server is for 1 Eiger half module\n"); + //#endif + + + //Allocation of memory + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorChips=malloc(n*NCHIP*sizeof(int)); + + detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); + detectorDacs=malloc(n*NDAC*sizeof(dacs_t)); + detectorAdcs=malloc(n*NADC*sizeof(dacs_t)); + detectorGain=malloc(n*NGAIN*sizeof(int)); + detectorOffset=malloc(n*NOFFSET*sizeof(int)); +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",detectorModules, detectorModules+n); + printf("chips from 0x%x to 0x%x\n",detectorChips, detectorChips+n*NCHIP); + printf("chans from 0x%x to 0x%x\n",detectorChans, detectorChans+n*NCHIP*NCHAN); + printf("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs+n*NDAC); + printf("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs+n*NADC); + printf("gains from 0x%x to 0x%x\n",detectorGain, detectorGain+n*NGAIN); + printf("offsets from 0x%x to 0x%x\n",detectorOffset, detectorOffset+n*NOFFSET); +#endif + for (imod=0; imoddacs=detectorDacs+imod*NDAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*NADC; + (detectorModules+imod)->chipregs=detectorChips+imod*NCHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*NCHIP*NCHAN; + (detectorModules+imod)->ndac=NDAC; + (detectorModules+imod)->nadc=NADC; + (detectorModules+imod)->nchip=NCHIP; + (detectorModules+imod)->nchan=NCHIP*NCHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + for(i=0;indac;i++) + setDAC((enum detDacIndex)i,default_dac_values[i],(detectorModules)->module,0,retval); + + //setting default measurement parameters + setTimer(FRAME_NUMBER,1); + setTimer(ACQUISITION_TIME,1E9); + setTimer(SUBFRAME_ACQUISITION_TIME,DEFAULT_SUBFRAME_EXPOSURE_VAL); + setTimer(FRAME_PERIOD,1E9); + setDynamicRange(16); + eiger_photonenergy = -1; + setReadOutFlags(NONPARALLEL); + setSpeed(0,1);//clk_devider,half speed + setHighVoltage(0,0); + setIODelay(650,0); + setTiming(AUTO_TIMING); + //SetPhotonEnergyCalibrationParameters(-5.8381e-5,1.838515,5.09948e-7,-4.32390e-11,1.32527e-15); + setRateCorrection(0); //deactivate rate correction + int enable[2] = {0,1}; + setExternalGating(enable);//disable external gating + Feb_Control_SetInTestModeVariable(0); + Feb_Control_CheckSetup(); + + //print detector mac and ip + printf("mac read from detector: %llx\n",getDetectorMAC()); + printf("ip read from detector: %x\n",getDetectorIP()); + + + printf("\n"); + return 1; +} + +int initDetectorStop(){ + getModuleConfiguration(); + Feb_Interface_FebInterface(); + Feb_Control_FebControl(); + Feb_Control_Init(master,top,getDetectorNumber()); + printf("FEB Initialization done\n"); + /* Beb_Beb(-1); + printf("BEB constructor done\n");*/ + + printf("\n"); + return 1; +} + + + +void getModuleConfiguration(){ + int *m=&master; + int *t=⊤ + /*if(getDetectorNumber() == 0xbeb015){ + master = 1; + top = 1; + }*/ + Beb_GetModuleCopnfiguration(m,t); + if(top) printf("*************** TOP ***************\n"); + else printf("*************** BOTTOM ***************\n"); + if(master) printf("*************** MASTER ***************\n"); + else printf("*************** SLAVE ***************\n"); +} + + + +int setNMod(int nm, enum dimension dim){ + return 1; +} + + + +int getNModBoard(enum dimension arg){ + return 1; +} + + + +int64_t getModuleId(enum idMode arg, int imod){ + + /**/ + return -1; +} + + + + +int64_t getDetectorId(enum idMode arg){ + int64_t retval = -1; + + switch(arg){ + case DETECTOR_SERIAL_NUMBER: + retval = getDetectorNumber();/** to be implemented with mac? */ + break; + case DETECTOR_FIRMWARE_VERSION: + return (int64_t)Beb_GetFirmwareRevision(); + case SOFTWARE_FIRMWARE_API_VERSION: + return (int64_t)Beb_GetFirmwareSoftwareAPIVersion(); + case DETECTOR_SOFTWARE_VERSION: + retval= SVNREV; + retval= (retval <<32) | SVNDATE; + //cprintf(BLUE,"git date:%x, git rev:%x\n",SVNDATE,SVNREV); + break; + default: + break; + } + + return retval; +} + + + +int getDetectorNumber(){ + int res=0; + + //execute and get address + char output[255]; + FILE* sysFile = popen("more /home/root/executables/detid.txt", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + sscanf(output,"%d",&res); + printf("detector id: %d\n",res); + +/* + int res=0; + char hostname[100]; + if (gethostname(hostname, sizeof hostname) == 0) + puts(hostname); + else + perror("gethostname"); + sscanf(hostname,"%x",&res); +*/ + return res; +} + + +u_int64_t getDetectorMAC() { + char mac[255]=""; + u_int64_t res=0; + + //execute and get address + char output[255]; + FILE* sysFile = popen("more /sys/class/net/eth0/address", "r"); + //FILE* sysFile = popen("ifconfig eth0 | grep HWaddr | cut -d \" \" -f 11", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + + //getting rid of ":" + char * pch; + pch = strtok (output,":"); + while (pch != NULL){ + strcat(mac,pch); + pch = strtok (NULL, ":"); + } + sscanf(mac,"%llx",&res); + //increment by 1 for 10g + if(send_to_ten_gig) + res++; + //printf("mac:%llx\n",res); + + return res; +} + + + +int getDetectorIP(){ + char temp[50]=""; + int res=0; + //execute and get address + char output[255]; + FILE* sysFile = popen("ifconfig | grep 'inet addr:'| grep -v '127.0.0.1' | cut -d: -f2", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + + //converting IPaddress to hex. + char* pcword = strtok (output,"."); + while (pcword != NULL) { + sprintf(output,"%02x",atoi(pcword)); + strcat(temp,output); + pcword = strtok (NULL, "."); + } + strcpy(output,temp); + sscanf(output, "%x", &res); + //printf("ip:%x\n",res); + + return res; +} + + + +int moduleTest( enum digitalTestMode arg, int imod){ + //template testShiftIn from mcb_funcs.c + + //CHIP_TEST + //testShiftIn + //testShiftOut + //testShiftStSel + //testDataInOutMux + //testExtPulseMux + //testOutMux + //testFpgaMux + + return OK; +} + + + + + +int detectorTest( enum digitalTestMode arg){ + //templates from firmware_funcs.c + + //DETECTOR_FIRMWARE_TEST:testFpga() + //DETECTOR_MEMORY_TEST:testRAM() + //DETECTOR_BUS_TEST:testBus() + //DETECTOR_SOFTWARE_TEST:testFpga() + return OK; +} + + + + + + +void setDAC(enum detDacIndex ind, int val, int imod, int mV, int retval[]){ + + if(ind == VTHRESHOLD){ + int ret[5]; + setDAC(VCMP_LL,val,imod,mV,retval); + ret[0] = retval[mV]; + setDAC(VCMP_LR,val,imod,mV,retval); + ret[1] = retval[mV]; + setDAC(VCMP_RL,val,imod,mV,retval); + ret[2] = retval[mV]; + setDAC(VCMP_RR,val,imod,mV,retval); + ret[3] = retval[mV]; + setDAC(VCP,val,imod,mV,retval); + ret[4] = retval[mV]; + + + if((ret[0]== ret[1])&& + (ret[1]==ret[2])&& + (ret[2]==ret[3]) && + (ret[3]==ret[4])) + cprintf(GREEN,"vthreshold match\n"); + else{ + retval[0] = -1;retval[1] = -1; + cprintf(RED,"vthreshold mismatch 0:%d 1:%d 2:%d 3:%d\n", + ret[0],ret[1],ret[2],ret[3]); + } + return; + } + char iname[10]; + + if(((int)ind>=0)&&((int)ind= 0) + printf("Setting dac %d: %s to %d ",ind, iname,val); + else + printf("Getting dac %d: %s ",ind, iname); + if(mV) + printf("in mV\n"); + else + printf("in dac units\n"); +#endif + if(val >= 0) + Feb_Control_SetDAC(iname,val,mV); + int k; + Feb_Control_GetDAC(iname, &k,0); + retval[0] = k; + Feb_Control_GetDAC(iname,&k,1); + retval[1] = k; + + (detectorModules)->dacs[ind] = retval[0]; + +} + + +int setHighVoltage(int val, int imod){ + if(val!=-1){ + printf(" Setting High Voltage: %d\n",val); + if(!master) + eiger_highvoltage = val; + else if(Feb_Control_SetHighVoltage(val)) + eiger_highvoltage = val; + } + return eiger_highvoltage; +} + + +int getADC(enum detAdcIndex ind, int imod){ + int retval = -1; + char tempnames[6][20]={"FPGA EXT", "10GE","DCDC", "SODL", "SODR", "FPGA"}; + char cstore[255]; + + switch(ind){ + case TEMP_FPGA: + retval=getBebFPGATemp()*1000; + break; + case TEMP_FPGAFEBL: + retval=Feb_Control_GetLeftFPGATemp(); + break; + case TEMP_FPGAFEBR: + retval=Feb_Control_GetRightFPGATemp(); + break; + case TEMP_FPGAEXT: + case TEMP_10GE: + case TEMP_DCDC: + case TEMP_SODL: + case TEMP_SODR: + sprintf(cstore,"more /sys/class/hwmon/hwmon%d/device/temp1_input",ind); + FILE* sysFile = popen(cstore, "r"); + fgets(cstore, sizeof(cstore), sysFile); + pclose(sysFile); + sscanf(cstore,"%d",&retval); + break; + default: + return -1; + } + + printf("Temperature %s: %f°C\n",tempnames[ind],(double)retval/1000.00); + + return retval; +} + + +int setIODelay(int val, int imod){ + if(val!=-1){ + printf(" Setting IO Delay: %d\n",val); + if(Feb_Control_SetIDelays(Feb_Control_GetModuleNumber(),val)) + eiger_iodelay = val; + } + return eiger_iodelay; +} + + +int enableTenGigabitEthernet(int val){ + if(val!=-1){ + if(val>0) + send_to_ten_gig = 1; + else + send_to_ten_gig = 0; + //configuremac called from client + } +#ifdef VERBOSE + printf("10Gbe:%d\n",send_to_ten_gig); +#endif + return send_to_ten_gig; +} + + +int setCounterBit(int val){ + if(val!=-1){ + Feb_Control_Set_Counter_Bit(val); +#ifdef VERBOSE + printf("Counter Bit:%d\n",val); +#endif + } + + return Feb_Control_Get_Counter_Bit(); +} + + +int pulsePixel(int n, int x, int y){ + if(!Feb_Control_Pulse_Pixel(n,x,y)) + return FAIL; + return OK; +} + +int pulsePixelNMove(int n, int x, int y){ + if(!Feb_Control_PulsePixelNMove(n,x,y)) + return FAIL; + return OK; +} + +int pulseChip(int n){ + if(!Feb_Control_PulseChip(n)) + return FAIL; + return OK; +} + +int64_t setRateCorrection(int64_t custom_tau_in_nsec){//in nanosec (will never be -1) + + //deactivating rate correction + if(custom_tau_in_nsec==0){ + Feb_Control_SetRateCorrectionVariable(0); + return 0; + } + + int64_t tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec(); + int64_t subexp_in_nsec = Feb_Control_Get_RateTable_Subexptime_in_nsec(); + //same setting + if((tau_in_nsec == custom_tau_in_nsec) && (subexp_in_nsec == Feb_Control_GetSubFrameExposureTime())){ + printf("Rate Table already created before: Same Tau %lldns, Same subexptime %lldns\n", + tau_in_nsec,subexp_in_nsec); + } + //different setting, calculate table + else{ + int ret = Feb_Control_SetRateCorrectionTau(custom_tau_in_nsec); + if(ret<=0){ + cprintf(RED,"Rate correction failed. Deactivating rate correction\n"); + Feb_Control_SetRateCorrectionVariable(0); + return ret; + } + } + //activating rate correction + Feb_Control_SetRateCorrectionVariable(1); + printf("Rate Correction Value set to %lld ns\n",(long long int)Feb_Control_Get_RateTable_Tau_in_nsec()); +#ifdef VERBOSE + Feb_Control_PrintCorrectedValues(); +#endif + + return Feb_Control_Get_RateTable_Tau_in_nsec(); +} + +int getRateCorrectionEnable(){ + return Feb_Control_GetRateCorrectionVariable(); +} + +int getDefaultSettingsTau_in_nsec(){ + return default_tau_from_file; +} + +int64_t getCurrentTau(){ + if(!getRateCorrectionEnable()) + return 0; + else + return Feb_Control_Get_RateTable_Tau_in_nsec(); +} + +void setDefaultSettingsTau_in_nsec(int t){ + default_tau_from_file = t; +} + +int setModule(sls_detector_module myMod, int* gain, int* offset,int* delay){ + int retval[2]; + int i; + + //#ifdef VERBOSE + printf("Setting module with settings %d\n",myMod.reg); + //#endif + + //set the settings variable + setSettings( (enum detectorSettings)myMod.reg,-1); + + //set the gains and offset variables locally + for(i=0;i=0){ + detectorGain[i] = gain[i]; + printf("gain[%d]:%d\n",i,detectorGain[i]); + }else cprintf(RED,"gain not changed\n"); + } + for(i=0;i=0){ + detectorOffset[i] = offset[i]; + printf("offset[%d]:%d\n",i,detectorOffset[i]); + }else cprintf(RED,"offset not changed\n"); + } + + if(setIODelay(*delay, -1)!= (*delay)){ + cprintf(RED,"could not set iodelay %d\n",*delay); + return FAIL; + } + + //copy module locally + if (detectorModules) + copyModule(detectorModules,&myMod); + + //set dac values + for(i=0;ichanregs[ich++]=tt[ip++]; + } + if (ichip<3) { + ip++; + ip++; + } + } + } + + //copy to local copy as well + if (detectorModules) + copyModule(myMod,detectorModules); + else + return FAIL; + return OK; +} + + + + + + +int getThresholdEnergy(int imod){ + printf(" Getting Threshold energy\n"); + return eiger_photonenergy; +} + + +int setThresholdEnergy(int ev, int imod){ + printf(" Setting threshold energy:%d\n",ev); + int retval[2],i; + int thrvalue[NGAIN]; + int average=0; + if(ev >= 0) { + + enum detDacIndex ind[NGAIN]={VCMP_LL,VCMP_LR,VCMP_RL, VCMP_RR}; + const char* vcmp[4]={"vcmp_ll","vcmp_lr","vcmp_rl","vcmp_rr"}; + int valid=0; + + //calculate thrvalues for dacs + for(i=0;i=0 && thrvalue[i]<2001)valid++; + }//ngains + + if( valid == NGAIN){ + eiger_photonenergy = ev; + for(i=0;i= 0){ + printf(" Setting number of frames: %d * %d\n",(unsigned int)val,eiger_ncycles); + if(Feb_Control_SetNExposures((unsigned int)val*eiger_ncycles)){ + eiger_nexposures = val; + //SetDestinationParameters(EigerGetNumberOfExposures()*EigerGetNumberOfCycles()); + on_dst = 0; + int i; + for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested + ndsts_in_use = 1; + nimages_per_request = eiger_nexposures * eiger_ncycles; + } + }return eiger_nexposures; + + case ACQUISITION_TIME: + if(val >= 0){ + printf(" Setting exp time: %fs\n",val/(1E9)); + Feb_Control_SetExposureTime(val/(1E9)); + } + return (Feb_Control_GetExposureTime()*(1E9)); + + case SUBFRAME_ACQUISITION_TIME: + if(val >= 0){ + printf(" Setting sub exp time: %lldns\n",(long long int)val/10); + Feb_Control_SetSubFrameExposureTime(val/10); + } + return (Feb_Control_GetSubFrameExposureTime()); + + + case FRAME_PERIOD: + if(val >= 0){ + printf(" Setting acq period: %fs\n",val/(1E9)); + Feb_Control_SetExposurePeriod(val/(1E9)); + } + return (Feb_Control_GetExposurePeriod()*(1E9)); + /* case DELAY_AFTER_TRIGGER: + if(val >= 0) + EigerSetNumberOfExposures((unsigned int)val); + return EigerGetNumberOfExposures(); + + case GATES_NUMBER: + if(val >= 0) + EigerSetNumberOfGates((unsigned int)val); + return EigerGetNumberOfGates(); + + case PROBES_NUMBER: + if(val >= 0) + EigerSetNumberOfExposures((unsigned int)val); + return EigerGetNumberOfExposures();*/ + case CYCLES_NUMBER: + if(val >= 0){ + printf(" Setting number of triggers: %d * %d\n",(unsigned int)val,eiger_nexposures); + if(Feb_Control_SetNExposures((unsigned int)val*eiger_nexposures)){ + eiger_ncycles = val; + //SetDestinationParameters(EigerGetNumberOfExposures()*EigerGetNumberOfCycles()); + on_dst = 0; + int i; + for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested + nimages_per_request = eiger_nexposures * eiger_ncycles; + } + }return eiger_ncycles; + default: + printf("unknown timer index: %d\n",ind); + break; + } + + return -1; +} + + + + +int64_t getTimeLeft(enum timerIndex ind){ + + return -1; +} + + + +int setDynamicRange(int dr){ + if(dr > 0){ + printf(" Setting dynamic range: %d\n",dr); + if(Feb_Control_SetDynamicRange(dr)){ + + //EigerSetBitMode(dr); + on_dst = 0; + int i; + for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested + if(Beb_SetUpTransferParameters(dr)) + eiger_dynamicrange = dr; + else printf("ERROR:Could not set bit mode in the back end\n"); + } + } + //make sure back end and front end have the same bit mode + dr= Feb_Control_GetDynamicRange(); + + return dr; +} + + + +enum readOutFlags setReadOutFlags(enum readOutFlags val){ + + enum readOutFlags retval = GET_READOUT_FLAGS; + if(val!=GET_READOUT_FLAGS){ + + + if(val&0xF0000){ + switch(val){ + case PARALLEL: val=E_PARALLEL; printf(" Setting Read out Flag: Parallel\n"); break; + case NONPARALLEL: val=E_NON_PARALLEL; printf(" Setting Read out Flag: Non Parallel\n"); break; + case SAFE: val=E_SAFE; printf(" Setting Read out Flag: Safe\n"); break; + + default: + cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); + return -1; + } + printf(" Setting Read out Flag: %d\n",val); + if(Feb_Control_SetReadoutMode(val)) + eiger_readoutmode = val; + else return -1; + + }else{ + switch(val){ + case STORE_IN_RAM: val=1; printf(" Setting Read out Flag: Store in Ram\n"); break; + case CONTINOUS_RO: val=0; printf(" Setting Read out Flag: Continuous Readout\n"); break; + + default: + cprintf(RED,"Cannot set unknown readout flag. 0x%x\n", val); + return -1; + } + printf(" Setting store in ram variable: %d\n",val); + eiger_storeinmem = val; + + } + } + + switch(eiger_readoutmode){ + case E_PARALLEL: retval=PARALLEL; break; + case E_NON_PARALLEL: retval=NONPARALLEL; break; + case E_SAFE: retval=SAFE; break; + } + + switch(eiger_storeinmem){ + case 0: retval|=CONTINOUS_RO; break; + case 1: retval|=STORE_IN_RAM; break; + } + printf("Read out Flag: 0x%x\n",retval); + return retval; +} + + + + +int setROI(int n, ROI arg[], int *retvalsize, int *ret){ + return FAIL; +} + + + +int setSpeed(enum speedVariable arg, int val){ + if(val != -1){ + printf(" Setting Read out Speed: %d\n",val); + if(Feb_Control_SetReadoutSpeed(val)) + eiger_readoutspeed = val; + } + return eiger_readoutspeed; +} + + + +int executeTrimming(enum trimMode mode, int par1, int par2, int imod){ + return FAIL; +} + + +int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport, int udpport2, int ival){ + if (detectormacadd != getDetectorMAC()){ + printf("*************************************************\n"); + printf("WARNING: actual detector mac address %llx does not match the one from client %llx\n",getDetectorMAC(),detectormacadd); + detectormacadd = getDetectorMAC(); + printf("WARNING: Matched detectormac to the hardware mac now\n"); + printf("*************************************************\n"); + } + //only for 1Gbe + if(!send_to_ten_gig){ + if (detipad != getDetectorIP()){ + printf("*************************************************\n"); + printf("WARNING: actual detector ip address %x does not match the one from client %x\n",getDetectorIP(),detipad); + detipad = getDetectorIP(); + printf("WARNING: Matched detector ip to the hardware ip now\n"); + printf("*************************************************\n"); + } + } + + char src_mac[50], src_ip[50],dst_mac[50], dst_ip[50]; + int src_port = 0xE185; + sprintf(src_ip,"%d.%d.%d.%d",(detipad>>24)&0xff,(detipad>>16)&0xff,(detipad>>8)&0xff,(detipad)&0xff); + sprintf(dst_ip,"%d.%d.%d.%d",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff); + sprintf(src_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((detectormacadd>>40)&0xFF), + (unsigned int)((detectormacadd>>32)&0xFF), + (unsigned int)((detectormacadd>>24)&0xFF), + (unsigned int)((detectormacadd>>16)&0xFF), + (unsigned int)((detectormacadd>>8)&0xFF), + (unsigned int)((detectormacadd>>0)&0xFF)); + sprintf(dst_mac,"%02x:%02x:%02x:%02x:%02x:%02x",(unsigned int)((macad>>40)&0xFF), + (unsigned int)((macad>>32)&0xFF), + (unsigned int)((macad>>24)&0xFF), + (unsigned int)((macad>>16)&0xFF), + (unsigned int)((macad>>8)&0xFF), + (unsigned int)((macad>>0)&0xFF)); + + printf("src_port:%d\n",src_port); + printf("src_ip:%s\n",src_ip); + printf("dst_ip:%s\n",dst_ip); + printf("src_mac:%s\n",src_mac); + printf("dst_mac:%s\n",dst_mac); + + + int beb_num = BEB_NUM;//Feb_Control_GetModuleNumber(); + int header_number = 0; + int dst_port = udpport; + + printf("dst_port:%d\n\n",dst_port); + + int i=0; + /* for(i=0;i<32;i++){ modified for Aldo*/ + if(Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && + Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) + printf("set up left ok\n"); + else return -1; + /*}*/ + + header_number = 32; + dst_port = udpport2; + printf("dst_port:%d\n\n",dst_port); + + /*for(i=0;i<32;i++){*//** modified for Aldo*/ + if(Beb_SetBebSrcHeaderInfos(beb_num,send_to_ten_gig,src_mac,src_ip,src_port) && + Beb_SetUpUDPHeader(beb_num,send_to_ten_gig,header_number+i,dst_mac,dst_ip, dst_port)) + printf("set up right ok\n\n"); + else return -1; + /*}*/ + + on_dst = 0; + + for(i=0;i<32;i++) dst_requested[i] = 0; //clear dst requested + nimages_per_request=eiger_nexposures * eiger_ncycles; + + return 0; +} + + +int calculateDataBytes(){ + if(send_to_ten_gig) + return setDynamicRange(-1)*16*TEN_GIGA_BUFFER_SIZE; + else + return setDynamicRange(-1)*16*ONE_GIGA_BUFFER_SIZE; +} + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod){ + + int ichip, idac, ichan, iadc; + int ret=OK; + +#ifdef VERBOSE + printf("Copying module %x to module %x\n",srcMod,destMod); +#endif + + if (srcMod->module>=0) { +#ifdef VERBOSE + printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); +#endif + destMod->module=srcMod->module; + } + if (srcMod->serialnumber>=0){ + + destMod->serialnumber=srcMod->serialnumber; + } + if ((srcMod->nchip)>(destMod->nchip)) { + printf("Number of chip of source is larger than number of chips of destination\n"); + return FAIL; + } + if ((srcMod->nchan)>(destMod->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + if ((srcMod->ndac)>(destMod->ndac)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + if ((srcMod->nadc)>(destMod->nadc)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + +#ifdef VERBOSE + printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); + printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); + printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); + printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); + +#endif + destMod->ndac=srcMod->ndac; + destMod->nadc=srcMod->nadc; + destMod->nchip=srcMod->nchip; + destMod->nchan=srcMod->nchan; + if (srcMod->reg>=0) + destMod->reg=srcMod->reg; +#ifdef VERBOSE + printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); +#endif + if (srcMod->gain>=0) + destMod->gain=srcMod->gain; + if (srcMod->offset>=0) + destMod->offset=srcMod->offset; + + for (ichip=0; ichip<(srcMod->nchip); ichip++) { + if (*((srcMod->chipregs)+ichip)>=0) + *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); + } + for (ichan=0; ichan<(srcMod->nchan); ichan++) { + if (*((srcMod->chanregs)+ichan)>=0) + *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); + } + for (idac=0; idac<(srcMod->ndac); idac++) { + if (*((srcMod->dacs)+idac)>=0) + *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } + for (iadc=0; iadc<(srcMod->nadc); iadc++) { + if (*((srcMod->adcs)+iadc)>=0) + *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); + } + return ret; +} + + + +int getTotalNumberOfChannels(){return getNumberOfChannelsPerModule();} +int getTotalNumberOfChips(){return NCHIP;} +int getTotalNumberOfModules(){return 1;} +int getNumberOfChannelsPerChip(){return NCHAN;} +int getNumberOfChannelsPerModule(){return getNumberOfChannelsPerChip() * getTotalNumberOfChips();} +int getNumberOfChipsPerModule(){return NCHIP;} +int getNumberOfDACsPerModule(){return NDAC;} +int getNumberOfADCsPerModule(){return NADC;} +int getNumberOfGainsPerModule(){return NGAIN;} +int getNumberOfOffsetsPerModule(){return NOFFSET;} + + + + + +enum externalSignalFlag getExtSignal(int signalindex){ + return GET_EXTERNAL_SIGNAL_FLAG; +} + + + + + +enum externalSignalFlag setExtSignal(int signalindex, enum externalSignalFlag flag){ + return getExtSignal(signalindex); +} + + + + + + +enum externalCommunicationMode setTiming( enum externalCommunicationMode arg){ + enum externalCommunicationMode ret=GET_EXTERNAL_COMMUNICATION_MODE; + if(arg != GET_EXTERNAL_COMMUNICATION_MODE){ + switch((int)arg){ + case AUTO_TIMING: ret = 0; break; + case TRIGGER_EXPOSURE: ret = 2; break; + case BURST_TRIGGER: ret = 1; break; + case GATE_FIX_NUMBER: ret = 3; break; + } + printf(" Setting Triggering Mode: %d\n",(int)ret); + if(Feb_Control_SetTriggerMode(ret,1)) + eiger_triggermode = ret; + } + + ret = eiger_triggermode; + switch((int)ret){ + case 0: ret = AUTO_TIMING; break; + case 2: ret = TRIGGER_EXPOSURE; break; + case 1: ret = BURST_TRIGGER; break; + case 3: ret = GATE_FIX_NUMBER; break; + default: + printf("Unknown trigger mode found %d\n",ret); + ret = 0; + } + return ret; +} + + +void setExternalGating(int enable[]){ + if(enable>=0){ + Feb_Control_SetExternalEnableMode(enable[0], enable[1]);//enable = 0 or 1, polarity = 0 or 1 , where 1 is positive + eiger_extgating = enable[0]; + eiger_extgatingpolarity = enable[1]; + } + enable[0] = eiger_extgating; + enable[1] = eiger_extgatingpolarity; +} + + +enum masterFlags setMaster(enum masterFlags arg){ + //if(arg != GET_MASTER) + // masterMode = arg; + + return NO_MASTER; +} + + + +enum synchronizationMode setSynchronization(enum synchronizationMode arg){ + return NO_SYNCHRONIZATION; +} + +void setAllTrimbits(int val){ + int ichan; + if(Feb_Control_SaveAllTrimbitsTo(val)){ +#ifdef VERBOSE + printf("Copying register %x value %d\n",destMod->reg,val); +#endif + if (detectorModules){ + for (ichan=0; ichan<(detectorModules->nchan); ichan++) { + *((detectorModules->chanregs)+ichan)=val; + } + } + }else printf("error in setting all trimbits to value\n"); +} + +int getAllTrimbits(){ + return *((detectorModules->chanregs)); +} + +int getBebFPGATemp(){ + return Beb_GetBebFPGATemp(); +} + + +int activate(int enable){ + int ret = Beb_Activate(enable); + Feb_Control_activate(ret); + return ret; +} + + +int setNetworkParameter(enum detNetworkParameter mode, int value){ + return Beb_SetNetworkParameter(mode, value); +} + +#endif diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.h b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.h new file mode 120000 index 000000000..345b8c029 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorFunctionList.h @@ -0,0 +1 @@ +../slsDetectorServer/slsDetectorFunctionList.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer.c b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer.c new file mode 120000 index 000000000..a7eb59acb --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer.c @@ -0,0 +1 @@ +../slsDetectorServer/slsDetectorServer.c \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_defs.h new file mode 100644 index 000000000..5e821bd73 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_defs.h @@ -0,0 +1,48 @@ +/* + * slsDetectorServer_defs.h + * + * Created on: Jan 24, 2013 + * Author: l_maliakal_d + */ + +#ifndef SLSDETECTORSERVER_DEFS_H_ +#define SLSDETECTORSERVER_DEFS_H_ + +//#include "sls_detector_defs.h" +#include + +#define GOODBYE -200 + +#define FEB_PORT 43210 +#define BEB_PORT 43212 + +#define REQUIRED_FIRMWARE_VERSION 14 + +#define FIRMWAREREV 0xcaba //temporary should be in firmware + + +#define NCHAN 256*256 +#define NCHIP 4 +#define NDAC 16 +#define NADC 0 +#define NGAIN 4 +#define NOFFSET 4 + +#define NMAXMODX 1 +#define NMAXMODY 1 +#define NMAXMOD NMAXMODX*NMAXMODY +#define NCHANS NCHAN*NCHIP*NMAXMOD +#define NDACS NDAC*NMAXMOD + + +#define DYNAMIC_RANGE 16 + + +enum detDacIndex{SVP,VTR,VRF,VRS,SVN,VTGSTV,VCMP_LL,VCMP_LR,CAL,VCMP_RL,RXB_RB,RXB_LB,VCMP_RR,VCP,VCN,VIS,VTHRESHOLD}; + +enum detAdcIndex{TEMP_FPGAEXT, TEMP_10GE, TEMP_DCDC, TEMP_SODL, TEMP_SODR, TEMP_FPGA, TEMP_FPGAFEBL, TEMP_FPGAFEBR}; + +enum detNetworkParameter{TXN_LEFT, TXN_RIGHT, TXN_FRAME,FLOWCTRL_10G}; + + +#endif /* SLSDETECTORSERVER_DEFS_H_ */ diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_funcs.c b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_funcs.c new file mode 120000 index 000000000..a7532ccd4 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_funcs.c @@ -0,0 +1 @@ +../slsDetectorServer/slsDetectorServer_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_funcs.h b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_funcs.h new file mode 120000 index 000000000..7569daf47 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/slsDetectorServer_funcs.h @@ -0,0 +1 @@ +../slsDetectorServer/slsDetectorServer_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/sls_detector_defs.h b/slsDetectorSoftware/eigerDetectorServer/sls_detector_defs.h new file mode 120000 index 000000000..c5062e03f --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/sls_detector_defs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/sls_detector_funcs.h b/slsDetectorSoftware/eigerDetectorServer/sls_detector_funcs.h new file mode 120000 index 000000000..844b67129 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/sls_detector_funcs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/sls_receiver_defs.h b/slsDetectorSoftware/eigerDetectorServer/sls_receiver_defs.h new file mode 120000 index 000000000..1de31caf5 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/sls_receiver_defs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/sls_receiver_funcs.h b/slsDetectorSoftware/eigerDetectorServer/sls_receiver_funcs.h new file mode 120000 index 000000000..c2ea4ded9 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/sls_receiver_funcs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/eigerDetectorServer/xfs_types.h b/slsDetectorSoftware/eigerDetectorServer/xfs_types.h new file mode 100644 index 000000000..cd092bbd6 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/xfs_types.h @@ -0,0 +1,52 @@ +#ifndef __XFS_TYPES_H__ +#define __XFS_TYPES_H__ + +//#include "types.h" +#include +/******************************************************************************/ +/* types */ +/******************************************************************************/ + +typedef unsigned int xfs_u32; +typedef unsigned short xfs_u16; +typedef unsigned char xfs_u8; + +typedef signed int xfs_i32; +typedef signed short xfs_i16; +typedef signed char xfs_i8; + + +// UDP Header +struct udp_header_type +{ + // ethternet frame (14 byte) + uint8_t dst_mac[6]; + uint8_t src_mac[6]; + uint8_t len_type[2]; + + // ip header (20 byte) + uint8_t ver_headerlen[1]; + uint8_t service_type[1]; + uint8_t total_length[2]; + uint8_t identification[2]; + uint8_t flags[1]; + uint8_t frag_offset[1]; + uint8_t time_to_live[1]; + uint8_t protocol[1]; + uint8_t ip_header_checksum[2]; + uint8_t src_ip[4]; + uint8_t dst_ip[4]; + + // udp header (8 byte) + uint8_t src_port[2]; + uint8_t dst_port[2]; + uint8_t udp_message_len[2]; + uint8_t udp_checksum[2]; + +}; + + + +#endif // __XFS_TYPES_H__ + + diff --git a/slsDetectorSoftware/eigerDetectorServer/xparameters.h b/slsDetectorSoftware/eigerDetectorServer/xparameters.h new file mode 100644 index 000000000..424ff8d15 --- /dev/null +++ b/slsDetectorSoftware/eigerDetectorServer/xparameters.h @@ -0,0 +1,532 @@ +/* ONLY THOSE ARE USED IN THIS SOFTWARE. If one of those is modified in xilinx compilation, this file should be replaced with updated values +XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR +XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_RIGHT_BASEADDR +XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_LEFT_BASEADDR +XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR +XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR +XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR +*/ +/******************************************************************* +* +* CAUTION: This file is automatically generated by libgen. +* Version: Xilinx EDK 12.4 EDK_MS4.81d +* DO NOT EDIT. +* +* Copyright (c) 1995-2010 Xilinx, Inc. All rights reserved. + +* +* Description: Driver parameters +* +*******************************************************************/ + +#define STDIN_BASEADDRESS 0xC0000000 +#define STDOUT_BASEADDRESS 0xC0000000 + +/******************************************************************/ + + +/* Definitions for peripheral BB_IO_SHIFT_REG_PPC440 */ +#define XPAR_BB_IO_SHIFT_REG_PPC440_BASEADDR 0xD3000000 +#define XPAR_BB_IO_SHIFT_REG_PPC440_HIGHADDR 0xD300FFFF + + +/* Definitions for peripheral EIGER_BEB_SYNCH_IO_PPC440 */ +#define XPAR_EIGER_BEB_SYNCH_IO_PPC440_BASEADDR 0xD3100000 +#define XPAR_EIGER_BEB_SYNCH_IO_PPC440_HIGHADDR 0xD310FFFF + + +/* Definitions for peripheral PLB_BRAM_10G */ +#define XPAR_PLB_BRAM_10G_MEM0_BASEADDR 0xD4100000 +#define XPAR_PLB_BRAM_10G_MEM0_HIGHADDR 0xD410FFFF + + +/* Definitions for peripheral PLB_BRAM_TEMAC */ +#define XPAR_PLB_BRAM_TEMAC_MEM0_BASEADDR 0xD4000000 +#define XPAR_PLB_BRAM_TEMAC_MEM0_HIGHADDR 0xD400FFFF + + +/* Definitions for peripheral PLB_GPIO_SYS */ +#define XPAR_PLB_GPIO_SYS_BASEADDR 0xD1000000 +#define XPAR_PLB_GPIO_SYS_HIGHADDR 0xD100FFFF + +/** Command Generator */ +#define XPAR_CMD_GENERATOR 0xC5000000 + + +/** Version Numbers */ +#define XPAR_VERSION 0xc6000000 + +/* Definitions for peripheral PLB_GPIO_TEST */ +#define XPAR_PLB_GPIO_TEST_BASEADDR 0xD1010000 +#define XPAR_PLB_GPIO_TEST_HIGHADDR 0xD101FFFF + + +/* Definitions for peripheral PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT */ +#define XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR 0xC4100000 +#define XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_HIGHADDR 0xC410FFFF + +/* Definitions for a new memory */ +//#define XPAR_PLB_LL_NEW_MEMORY 0xD1000000//0xD1000084//0xC4200000 + + +/* Definitions for peripheral PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT */ +#define XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_BASEADDR 0xC4110000 +#define XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_RIGHT_HIGHADDR 0xC411FFFF + + +/* Definitions for peripheral PLB_LL_FIFO_AURORA_RX4_TX1_LEFT */ +#define XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_LEFT_BASEADDR 0xC4120000 +#define XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_LEFT_HIGHADDR 0xC412FFFF + + +/* Definitions for peripheral PLB_LL_FIFO_AURORA_RX4_TX1_RIGHT */ +#define XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_RIGHT_BASEADDR 0xC4130000 +#define XPAR_PLB_LL_FIFO_AURORA_RX4_TX1_RIGHT_HIGHADDR 0xC413FFFF + + +/* Definitions for peripheral PLB_LL_FIFO_XAUI_10G */ +#define XPAR_PLB_LL_FIFO_XAUI_10G_BASEADDR 0xC4140000 +#define XPAR_PLB_LL_FIFO_XAUI_10G_HIGHADDR 0xC414FFFF + + +/* Definitions for peripheral PLB_V46_CPU_TO_PLB_V46_BRIDGED */ +#define XPAR_PLB_V46_CPU_TO_PLB_V46_BRIDGED_BRIDGE_BASEADDR 0xCFFF0000 +#define XPAR_PLB_V46_CPU_TO_PLB_V46_BRIDGED_BRIDGE_HIGHADDR 0xCFFFFFFF +#define XPAR_PLB_V46_CPU_TO_PLB_V46_BRIDGED_RNG0_BASEADDR 0xD0000000 +#define XPAR_PLB_V46_CPU_TO_PLB_V46_BRIDGED_RNG0_HIGHADDR 0xDFFFFFFF + + +/* Definitions for peripheral PPC_SRAM */ +#define XPAR_PPC_SRAM_BASEADDR 0x00000000 +#define XPAR_PPC_SRAM_HIGHADDR 0x01FFFFFF + + +/******************************************************************/ + + +/* Definitions for peripheral PFLASH */ +#define XPAR_PFLASH_NUM_BANKS_MEM 1 + + +/******************************************************************/ + +/* Definitions for peripheral PFLASH */ +#define XPAR_PFLASH_MEM0_BASEADDR 0xE0000000 +#define XPAR_PFLASH_MEM0_HIGHADDR 0xE3FFFFFF + +/******************************************************************/ + +/* Canonical definitions for peripheral PFLASH */ +#define XPAR_EMC_0_NUM_BANKS_MEM 1 +#define XPAR_EMC_0_MEM0_BASEADDR 0xE0000000 +#define XPAR_EMC_0_MEM0_HIGHADDR 0xE3FFFFFF + +/******************************************************************/ + +/* Definitions for driver PLB_SHT1X_IF */ +#define XPAR_PLB_SHT1X_IF_NUM_INSTANCES 2 + +/* Definitions for peripheral PLB_SHT1X_IF_CH1 */ +#define XPAR_PLB_SHT1X_IF_CH1_DEVICE_ID 0 +#define XPAR_PLB_SHT1X_IF_CH1_BASEADDR 0xD2200000 +#define XPAR_PLB_SHT1X_IF_CH1_HIGHADDR 0xD220FFFF + + +/* Definitions for peripheral PLB_SHT1X_IF_CH2 */ +#define XPAR_PLB_SHT1X_IF_CH2_DEVICE_ID 1 +#define XPAR_PLB_SHT1X_IF_CH2_BASEADDR 0xD2210000 +#define XPAR_PLB_SHT1X_IF_CH2_HIGHADDR 0xD221FFFF + + +/******************************************************************/ + +/* Definitions for driver UARTLITE */ +#define XPAR_XUARTLITE_NUM_INSTANCES 1 + +/* Definitions for peripheral RS232 */ +#define XPAR_RS232_BASEADDR 0xC0000000 +#define XPAR_RS232_HIGHADDR 0xC000FFFF +#define XPAR_RS232_DEVICE_ID 0 +#define XPAR_RS232_BAUDRATE 115200 +#define XPAR_RS232_USE_PARITY 0 +#define XPAR_RS232_ODD_PARITY 0 +#define XPAR_RS232_DATA_BITS 8 + + +/******************************************************************/ + + +/* Canonical definitions for peripheral RS232 */ +#define XPAR_UARTLITE_0_DEVICE_ID XPAR_RS232_DEVICE_ID +#define XPAR_UARTLITE_0_BASEADDR 0xC0000000 +#define XPAR_UARTLITE_0_HIGHADDR 0xC000FFFF +#define XPAR_UARTLITE_0_BAUDRATE 115200 +#define XPAR_UARTLITE_0_USE_PARITY 0 +#define XPAR_UARTLITE_0_ODD_PARITY 0 +#define XPAR_UARTLITE_0_DATA_BITS 8 +#define XPAR_UARTLITE_0_SIO_CHAN 1 + + +/******************************************************************/ + +/* Definitions for driver SPI */ +#define XPAR_XSPI_NUM_INSTANCES 2 + +/* Definitions for peripheral SPI_FLASH */ +#define XPAR_SPI_FLASH_DEVICE_ID 0 +#define XPAR_SPI_FLASH_BASEADDR 0xD2000000 +#define XPAR_SPI_FLASH_HIGHADDR 0xD200FFFF +#define XPAR_SPI_FLASH_FIFO_EXIST 1 +#define XPAR_SPI_FLASH_SPI_SLAVE_ONLY 0 +#define XPAR_SPI_FLASH_NUM_SS_BITS 1 +#define XPAR_SPI_FLASH_NUM_TRANSFER_BITS 8 + + +/* Definitions for peripheral XPS_SPI_FEB_CFG */ +#define XPAR_XPS_SPI_FEB_CFG_DEVICE_ID 1 +#define XPAR_XPS_SPI_FEB_CFG_BASEADDR 0xD2010000 +#define XPAR_XPS_SPI_FEB_CFG_HIGHADDR 0xD201FFFF +#define XPAR_XPS_SPI_FEB_CFG_FIFO_EXIST 1 +#define XPAR_XPS_SPI_FEB_CFG_SPI_SLAVE_ONLY 0 +#define XPAR_XPS_SPI_FEB_CFG_NUM_SS_BITS 2 +#define XPAR_XPS_SPI_FEB_CFG_NUM_TRANSFER_BITS 8 + + +/******************************************************************/ + + +/* Canonical definitions for peripheral SPI_FLASH */ +#define XPAR_SPI_0_DEVICE_ID XPAR_SPI_FLASH_DEVICE_ID +#define XPAR_SPI_0_BASEADDR 0xD2000000 +#define XPAR_SPI_0_HIGHADDR 0xD200FFFF +#define XPAR_SPI_0_FIFO_EXIST 1 +#define XPAR_SPI_0_SPI_SLAVE_ONLY 0 +#define XPAR_SPI_0_NUM_SS_BITS 1 +#define XPAR_SPI_0_NUM_TRANSFER_BITS 8 + + +/* Canonical definitions for peripheral XPS_SPI_FEB_CFG */ +#define XPAR_SPI_1_DEVICE_ID XPAR_XPS_SPI_FEB_CFG_DEVICE_ID +#define XPAR_SPI_1_BASEADDR 0xD2010000 +#define XPAR_SPI_1_HIGHADDR 0xD201FFFF +#define XPAR_SPI_1_FIFO_EXIST 1 +#define XPAR_SPI_1_SPI_SLAVE_ONLY 0 +#define XPAR_SPI_1_NUM_SS_BITS 2 +#define XPAR_SPI_1_NUM_TRANSFER_BITS 8 + + +/******************************************************************/ + +/* Definitions for driver LLTEMAC */ +#define XPAR_XLLTEMAC_NUM_INSTANCES 1 + +/* Definitions for peripheral TEMAC_INST Channel 0 */ +#define XPAR_TEMAC_INST_CHAN_0_DEVICE_ID 0 +#define XPAR_TEMAC_INST_CHAN_0_BASEADDR 0xC3000000 +#define XPAR_TEMAC_INST_CHAN_0_HIGHADDR 0xC30FFFFF +#define XPAR_TEMAC_INST_CHAN_0_TXCSUM 0 +#define XPAR_TEMAC_INST_CHAN_0_RXCSUM 0 +#define XPAR_TEMAC_INST_CHAN_0_PHY_TYPE 4 +#define XPAR_TEMAC_INST_CHAN_0_TXVLAN_TRAN 0 +#define XPAR_TEMAC_INST_CHAN_0_RXVLAN_TRAN 0 +#define XPAR_TEMAC_INST_CHAN_0_TXVLAN_TAG 0 +#define XPAR_TEMAC_INST_CHAN_0_RXVLAN_TAG 0 +#define XPAR_TEMAC_INST_CHAN_0_TXVLAN_STRP 0 +#define XPAR_TEMAC_INST_CHAN_0_RXVLAN_STRP 0 +#define XPAR_TEMAC_INST_CHAN_0_MCAST_EXTEND 0 + +/* Canonical definitions for peripheral TEMAC_INST Channel 0 */ +#define XPAR_LLTEMAC_0_DEVICE_ID 0 +#define XPAR_LLTEMAC_0_BASEADDR 0xC3000000 +#define XPAR_LLTEMAC_0_HIGHADDR 0xC30FFFFF +#define XPAR_LLTEMAC_0_TXCSUM 0 +#define XPAR_LLTEMAC_0_RXCSUM 0 +#define XPAR_LLTEMAC_0_PHY_TYPE 4 +#define XPAR_LLTEMAC_0_TXVLAN_TRAN 0 +#define XPAR_LLTEMAC_0_RXVLAN_TRAN 0 +#define XPAR_LLTEMAC_0_TXVLAN_TAG 0 +#define XPAR_LLTEMAC_0_RXVLAN_TAG 0 +#define XPAR_LLTEMAC_0_TXVLAN_STRP 0 +#define XPAR_LLTEMAC_0_RXVLAN_STRP 0 +#define XPAR_LLTEMAC_0_MCAST_EXTEND 0 +#define XPAR_LLTEMAC_0_INTR 1 + + +/* LocalLink TYPE Enumerations */ +#define XPAR_LL_FIFO 1 +#define XPAR_LL_DMA 2 + + +/* Canonical LocalLink parameters for TEMAC_INST */ + + +/******************************************************************/ + + +/* Definitions for peripheral XPS_BRAM_IF_CNTLR_PPC440 */ +#define XPAR_XPS_BRAM_IF_CNTLR_PPC440_BASEADDR 0xFFFC0000 +#define XPAR_XPS_BRAM_IF_CNTLR_PPC440_HIGHADDR 0xFFFFFFFF + + +/******************************************************************/ + +#define XPAR_INTC_MAX_NUM_INTR_INPUTS 5 +#define XPAR_XINTC_HAS_IPR 1 +#define XPAR_XINTC_USE_DCR 0 +/* Definitions for driver INTC */ +#define XPAR_XINTC_NUM_INSTANCES 1 + +/* Definitions for peripheral XPS_INTC_PPC440 */ +#define XPAR_XPS_INTC_PPC440_DEVICE_ID 0 +#define XPAR_XPS_INTC_PPC440_BASEADDR 0xC1000000 +#define XPAR_XPS_INTC_PPC440_HIGHADDR 0xC100FFFF +#define XPAR_XPS_INTC_PPC440_KIND_OF_INTR 0xFFFFFFF4 + + +/******************************************************************/ + +#define XPAR_INTC_SINGLE_BASEADDR 0xC1000000 +#define XPAR_INTC_SINGLE_HIGHADDR 0xC100FFFF +#define XPAR_INTC_SINGLE_DEVICE_ID XPAR_XPS_INTC_PPC440_DEVICE_ID +#define XPAR_XPS_LL_FIFO_TEMAC_IP2INTC_IRPT_MASK 0X000001 +#define XPAR_XPS_INTC_PPC440_XPS_LL_FIFO_TEMAC_IP2INTC_IRPT_INTR 0 +#define XPAR_TEMAC_INST_TEMACINTC0_IRPT_MASK 0X000002 +#define XPAR_XPS_INTC_PPC440_TEMAC_INST_TEMACINTC0_IRPT_INTR 1 +#define XPAR_XPS_TIMER_PPC440_INTERRUPT_MASK 0X000004 +#define XPAR_XPS_INTC_PPC440_XPS_TIMER_PPC440_INTERRUPT_INTR 2 +#define XPAR_SPI_FLASH_IP2INTC_IRPT_MASK 0X000008 +#define XPAR_XPS_INTC_PPC440_SPI_FLASH_IP2INTC_IRPT_INTR 3 +#define XPAR_RS232_INTERRUPT_MASK 0X000010 +#define XPAR_XPS_INTC_PPC440_RS232_INTERRUPT_INTR 4 + +/******************************************************************/ + +/* Canonical definitions for peripheral XPS_INTC_PPC440 */ +#define XPAR_INTC_0_DEVICE_ID XPAR_XPS_INTC_PPC440_DEVICE_ID +#define XPAR_INTC_0_BASEADDR 0xC1000000 +#define XPAR_INTC_0_HIGHADDR 0xC100FFFF +#define XPAR_INTC_0_KIND_OF_INTR 0xFFFFFFF4 + +#define XPAR_INTC_0_LLFIFO_0_VEC_ID XPAR_XPS_INTC_PPC440_XPS_LL_FIFO_TEMAC_IP2INTC_IRPT_INTR +#define XPAR_INTC_0_LLTEMAC_0_VEC_ID XPAR_XPS_INTC_PPC440_TEMAC_INST_TEMACINTC0_IRPT_INTR +#define XPAR_INTC_0_TMRCTR_0_VEC_ID XPAR_XPS_INTC_PPC440_XPS_TIMER_PPC440_INTERRUPT_INTR +#define XPAR_INTC_0_SPI_0_VEC_ID XPAR_XPS_INTC_PPC440_SPI_FLASH_IP2INTC_IRPT_INTR +#define XPAR_INTC_0_UARTLITE_0_VEC_ID XPAR_XPS_INTC_PPC440_RS232_INTERRUPT_INTR + +/******************************************************************/ + +/* Definitions for driver LLFIFO */ +#define XPAR_XLLFIFO_NUM_INSTANCES 1 + +/* Definitions for peripheral XPS_LL_FIFO_TEMAC */ +#define XPAR_XPS_LL_FIFO_TEMAC_DEVICE_ID 0 +#define XPAR_XPS_LL_FIFO_TEMAC_BASEADDR 0xC4000000 +#define XPAR_XPS_LL_FIFO_TEMAC_HIGHADDR 0xC400FFFF + + +/******************************************************************/ + +/* Canonical definitions for peripheral XPS_LL_FIFO_TEMAC */ +#define XPAR_LLFIFO_0_DEVICE_ID XPAR_XPS_LL_FIFO_TEMAC_DEVICE_ID +#define XPAR_LLFIFO_0_BASEADDR 0xC4000000 +#define XPAR_LLFIFO_0_HIGHADDR 0xC400FFFF + + +/******************************************************************/ + +/* Definitions for driver SYSMON */ +#define XPAR_XSYSMON_NUM_INSTANCES 1 + +/* Definitions for peripheral XPS_SYSMON_ADC_PPC440 */ +#define XPAR_XPS_SYSMON_ADC_PPC440_DEVICE_ID 0 +#define XPAR_XPS_SYSMON_ADC_PPC440_BASEADDR 0xD0010000 +#define XPAR_XPS_SYSMON_ADC_PPC440_HIGHADDR 0xD001FFFF +#define XPAR_XPS_SYSMON_ADC_PPC440_INCLUDE_INTR 1 + + +/******************************************************************/ + + +/* Canonical definitions for peripheral XPS_SYSMON_ADC_PPC440 */ +#define XPAR_SYSMON_0_DEVICE_ID XPAR_XPS_SYSMON_ADC_PPC440_DEVICE_ID +#define XPAR_SYSMON_0_BASEADDR 0xD0010000 +#define XPAR_SYSMON_0_HIGHADDR 0xD001FFFF +#define XPAR_SYSMON_0_INCLUDE_INTR 1 + + +/******************************************************************/ + +/* Definitions for driver TMRCTR */ +#define XPAR_XTMRCTR_NUM_INSTANCES 1 + +/* Definitions for peripheral XPS_TIMER_PPC440 */ +#define XPAR_XPS_TIMER_PPC440_DEVICE_ID 0 +#define XPAR_XPS_TIMER_PPC440_BASEADDR 0xC2000000 +#define XPAR_XPS_TIMER_PPC440_HIGHADDR 0xC200FFFF + + +/******************************************************************/ + + +/* Canonical definitions for peripheral XPS_TIMER_PPC440 */ +#define XPAR_TMRCTR_0_DEVICE_ID XPAR_XPS_TIMER_PPC440_DEVICE_ID +#define XPAR_TMRCTR_0_BASEADDR 0xC2000000 +#define XPAR_TMRCTR_0_HIGHADDR 0xC200FFFF + + +/******************************************************************/ + +/* Definitions for bus frequencies */ +#define XPAR_CPU_PPC440_MPLB_FREQ_HZ 100000000 +/******************************************************************/ + +/* Canonical definitions for bus frequencies */ +#define XPAR_PROC_BUS_0_FREQ_HZ 100000000 +/******************************************************************/ + +#define XPAR_CPU_PPC440_CORE_CLOCK_FREQ_HZ 400000000 +#define XPAR_PPC440_VIRTEX5_CORE_CLOCK_FREQ_HZ 400000000 +#define XPAR_CPU_PPC440_IDCR_BASEADDR 0x00000000 +/******************************************************************/ +#define XPAR_CPU_ID 0 +#define XPAR_PPC440_VIRTEX5_ID 0 +#define XPAR_PPC440_VIRTEX5_PIR 0b1111 +#define XPAR_PPC440_VIRTEX5_ENDIAN_RESET 0 +#define XPAR_PPC440_VIRTEX5_USER_RESET 0b0000 +#define XPAR_PPC440_VIRTEX5_INTERCONNECT_IMASK 0xffffffff +#define XPAR_PPC440_VIRTEX5_ICU_RD_FETCH_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_ICU_RD_SPEC_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_ICU_RD_TOUCH_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DCU_RD_LD_CACHE_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DCU_RD_NONCACHE_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DCU_RD_TOUCH_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DCU_RD_URGENT_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DCU_WR_FLUSH_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DCU_WR_STORE_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DCU_WR_URGENT_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DMA0_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DMA1_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DMA2_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_DMA3_PLB_PRIO 0b00 +#define XPAR_PPC440_VIRTEX5_IDCR_BASEADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_IDCR_HIGHADDR 0x000000FF +#define XPAR_PPC440_VIRTEX5_APU_CONTROL 0b00010000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_0 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_1 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_2 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_3 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_4 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_5 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_6 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_7 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_8 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_9 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_10 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_11 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_12 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_13 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_14 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_APU_UDI_15 0b000000000000000000000000 +#define XPAR_PPC440_VIRTEX5_PPC440MC_ADDR_BASE 0x00000000 +#define XPAR_PPC440_VIRTEX5_PPC440MC_ADDR_HIGH 0X01FFFFFF +#define XPAR_PPC440_VIRTEX5_PPC440MC_ROW_CONFLICT_MASK 0x00000000 +#define XPAR_PPC440_VIRTEX5_PPC440MC_BANK_CONFLICT_MASK 0x00000000 +#define XPAR_PPC440_VIRTEX5_PPC440MC_CONTROL 0X8140008F +#define XPAR_PPC440_VIRTEX5_PPC440MC_PRIO_ICU 4 +#define XPAR_PPC440_VIRTEX5_PPC440MC_PRIO_DCUW 3 +#define XPAR_PPC440_VIRTEX5_PPC440MC_PRIO_DCUR 2 +#define XPAR_PPC440_VIRTEX5_PPC440MC_PRIO_SPLB1 0 +#define XPAR_PPC440_VIRTEX5_PPC440MC_PRIO_SPLB0 1 +#define XPAR_PPC440_VIRTEX5_PPC440MC_ARB_MODE 0 +#define XPAR_PPC440_VIRTEX5_PPC440MC_MAX_BURST 8 +#define XPAR_PPC440_VIRTEX5_MPLB_AWIDTH 32 +#define XPAR_PPC440_VIRTEX5_MPLB_DWIDTH 128 +#define XPAR_PPC440_VIRTEX5_MPLB_NATIVE_DWIDTH 128 +#define XPAR_PPC440_VIRTEX5_MPLB_COUNTER 0x00000500 +#define XPAR_PPC440_VIRTEX5_MPLB_PRIO_ICU 4 +#define XPAR_PPC440_VIRTEX5_MPLB_PRIO_DCUW 3 +#define XPAR_PPC440_VIRTEX5_MPLB_PRIO_DCUR 2 +#define XPAR_PPC440_VIRTEX5_MPLB_PRIO_SPLB1 0 +#define XPAR_PPC440_VIRTEX5_MPLB_PRIO_SPLB0 1 +#define XPAR_PPC440_VIRTEX5_MPLB_ARB_MODE 0 +#define XPAR_PPC440_VIRTEX5_MPLB_SYNC_TATTRIBUTE 0 +#define XPAR_PPC440_VIRTEX5_MPLB_MAX_BURST 8 +#define XPAR_PPC440_VIRTEX5_MPLB_ALLOW_LOCK_XFER 1 +#define XPAR_PPC440_VIRTEX5_MPLB_READ_PIPE_ENABLE 1 +#define XPAR_PPC440_VIRTEX5_MPLB_WRITE_PIPE_ENABLE 1 +#define XPAR_PPC440_VIRTEX5_MPLB_WRITE_POST_ENABLE 1 +#define XPAR_PPC440_VIRTEX5_MPLB_P2P 0 +#define XPAR_PPC440_VIRTEX5_MPLB_WDOG_ENABLE 1 +#define XPAR_PPC440_VIRTEX5_SPLB0_AWIDTH 32 +#define XPAR_PPC440_VIRTEX5_SPLB0_DWIDTH 128 +#define XPAR_PPC440_VIRTEX5_SPLB0_NATIVE_DWIDTH 128 +#define XPAR_PPC440_VIRTEX5_SPLB0_SUPPORT_BURSTS 1 +#define XPAR_PPC440_VIRTEX5_SPLB0_USE_MPLB_ADDR 0 +#define XPAR_PPC440_VIRTEX5_SPLB0_NUM_MPLB_ADDR_RNG 0 +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG_MC_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG_MC_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG0_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG0_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG1_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG1_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG2_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG2_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG3_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB0_RNG3_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB0_NUM_MASTERS 1 +#define XPAR_PPC440_VIRTEX5_SPLB0_MID_WIDTH 1 +#define XPAR_PPC440_VIRTEX5_SPLB0_ALLOW_LOCK_XFER 1 +#define XPAR_PPC440_VIRTEX5_SPLB0_READ_PIPE_ENABLE 1 +#define XPAR_PPC440_VIRTEX5_SPLB0_PROPAGATE_MIRQ 0 +#define XPAR_PPC440_VIRTEX5_SPLB0_P2P -1 +#define XPAR_PPC440_VIRTEX5_SPLB1_AWIDTH 32 +#define XPAR_PPC440_VIRTEX5_SPLB1_DWIDTH 128 +#define XPAR_PPC440_VIRTEX5_SPLB1_NATIVE_DWIDTH 128 +#define XPAR_PPC440_VIRTEX5_SPLB1_SUPPORT_BURSTS 1 +#define XPAR_PPC440_VIRTEX5_SPLB1_USE_MPLB_ADDR 0 +#define XPAR_PPC440_VIRTEX5_SPLB1_NUM_MPLB_ADDR_RNG 0 +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG_MC_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG_MC_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG0_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG0_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG1_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG1_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG2_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG2_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG3_MPLB_BASEADDR 0xFFFFFFFF +#define XPAR_PPC440_VIRTEX5_SPLB1_RNG3_MPLB_HIGHADDR 0x00000000 +#define XPAR_PPC440_VIRTEX5_SPLB1_NUM_MASTERS 1 +#define XPAR_PPC440_VIRTEX5_SPLB1_MID_WIDTH 1 +#define XPAR_PPC440_VIRTEX5_SPLB1_ALLOW_LOCK_XFER 1 +#define XPAR_PPC440_VIRTEX5_SPLB1_READ_PIPE_ENABLE 1 +#define XPAR_PPC440_VIRTEX5_SPLB1_PROPAGATE_MIRQ 0 +#define XPAR_PPC440_VIRTEX5_SPLB1_P2P -1 +#define XPAR_PPC440_VIRTEX5_NUM_DMA 0 +#define XPAR_PPC440_VIRTEX5_DMA0_TXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA0_RXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA0_CONTROL 0b00000000 +#define XPAR_PPC440_VIRTEX5_DMA0_TXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DMA0_RXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DMA1_TXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA1_RXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA1_CONTROL 0b00000000 +#define XPAR_PPC440_VIRTEX5_DMA1_TXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DMA1_RXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DMA2_TXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA2_RXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA2_CONTROL 0b00000000 +#define XPAR_PPC440_VIRTEX5_DMA2_TXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DMA2_RXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DMA3_TXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA3_RXCHANNELCTRL 0x01010000 +#define XPAR_PPC440_VIRTEX5_DMA3_CONTROL 0b00000000 +#define XPAR_PPC440_VIRTEX5_DMA3_TXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DMA3_RXIRQTIMER 0b1111111111 +#define XPAR_PPC440_VIRTEX5_DCR_AUTOLOCK_ENABLE 1 +#define XPAR_PPC440_VIRTEX5_PPCDM_ASYNCMODE 0 +#define XPAR_PPC440_VIRTEX5_PPCDS_ASYNCMODE 0 +#define XPAR_PPC440_VIRTEX5_GENERATE_PLB_TIMESPECS 1 +#define XPAR_PPC440_VIRTEX5_HW_VER "1.01.a" + +/******************************************************************/ + diff --git a/slsDetectorSoftware/f90Interface/externPostProcessing.cpp b/slsDetectorSoftware/f90Interface/externPostProcessing.cpp new file mode 100644 index 000000000..92b83c576 --- /dev/null +++ b/slsDetectorSoftware/f90Interface/externPostProcessing.cpp @@ -0,0 +1,47 @@ +#include "externPostProcessing.h" + + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace std; + + + + +int externPostProcessing::InitDataset(int *nModules,int *chPerMod,int moduleMask[],int badChans[], double ffcoeff[], double fferr[], double* tDead, double angRadius[], double angOffset[], double angCentre[], double* totalOffset, double* binSize, double *sampleX, double *sampleY) + { + + init_dataset(nModules,chPerMod,moduleMask,badChans,ffcoeff,fferr,tDead,angRadius,angOffset,angCentre,totalOffset,binSize,sampleX,sampleY); + return 0; + + } + +int externPostProcessing::finalizeDataset(double ang[], double val[], double err[], int *np) +{ + finalize_dataset(ang, val, err, np); + return 0; +}; + + +int addFrame(double data[], double *pos, double *IO, double *expTime, const char *filename, int *var) +{ + add_frame(data, pos, i0, expTime, filename, var); + return 0; +}; + +int calculateFlatField(int* nModules, int *chPerMod, int modMask[], int badChanMask[], double data[], double ffCoeff[], double ffErr[]) +{ + calculate_flat_field(nModules, chPerMod, modMask, badChanMask, data, ffCoeff, ffErr); + return 0; +}; diff --git a/slsDetectorSoftware/f90Interface/externPostProcessing.h b/slsDetectorSoftware/f90Interface/externPostProcessing.h new file mode 100644 index 000000000..605865b91 --- /dev/null +++ b/slsDetectorSoftware/f90Interface/externPostProcessing.h @@ -0,0 +1,58 @@ +#ifndef EXTERNPOSTPROCESSING_H +#define EXTERNPOSTPROCESSING_H + + +#include "detectorData.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace std; + + + +extern "C" { + + void init_dataset(int *nMod, int *chPerMod, int* modMask, int *badChanMask, double *ffCoeff, double *ffErr, double *tDead, int *dir, double *angRadius, double *angOffset, double *angCenter, double *totalOff, double *binSize, double * sampleX, double* sampleY); +void finalize_dataset(double *outang, double *outval, double *outerr, int *np); + void add_frame(double *data, double *pos, double *i0, double *exptime, char *fn, double *var); +void calculate_flat_field(int *nMod, int *chPerMod, int *modMask,int *badChanMask, double *data, double *ffc, double *fferr); +} + + + +class externPostProcessing + +{ + + public: + externPostProcessing(){}; + virtual ~externPostProcessing(){}; + + + static int InitDataset(int *nModules,int *chPerMod,int moduleMask[],int badChans[], double ffcoeff[], double fferr[], double* tDead, int *dir, double angRadius[], double angOffset[], double angCentre[], double* totalOffset, double* binSize, double *sampleX, double *sampleY); + + + + static int finalizeDataset(double ang[], double val[], double err[], int *np); + + static int addFrame(double data[], double *pos, double *IO, double *expTime, const char *filename, int *var=0); + + static int calculateFlatField(int* nModules, int *chPerMod, int moduleMask[], int badChannelMask[], double ffData[], double ffCoeff[], double ffErr[]); + + + + + }; + + +#endif diff --git a/slsDetectorSoftware/f90Interface/sls_detector_analysis_f.f90 b/slsDetectorSoftware/f90Interface/sls_detector_analysis_f.f90 new file mode 100644 index 000000000..201371ef4 --- /dev/null +++ b/slsDetectorSoftware/f90Interface/sls_detector_analysis_f.f90 @@ -0,0 +1,174 @@ +module ax +USE,INTRINSIC :: ISO_C_BINDING +IMPLICIT NONE +integer(C_LONG) :: numberofmodules,totalnumberofchannels +real(C_DOUBLE) :: numberofbins +real(C_DOUBLE) :: bincenter(360000), binvalue(360000), binerror(360000) + +contains + + +subroutine initdataset(nmodules, chpmod, modulemask,badchanmask,ffcoeff,fferr,tdead,angradius,angoffset,angcenter, totaloffset, binsize, samplex, sampley) bind(c, name='init_dataset') +IMPLICIT NONE +integer(C_LONG), intent(IN) :: nmodules, chpmod +integer(C_LONG), intent(IN) :: modulemask(nmodules), badchanmask(nmodules*chpmod) +real(C_DOUBLE), intent(IN) :: ffcoeff(nmodules*chpmod), fferr(nmodules*chpmod) +real(C_DOUBLE), intent(IN) :: tdead, totaloffset,binsize, samplex, sampley +real(C_DOUBLE), intent(IN) :: angradius(nmodules), angoffset(nmodules), angcenter(nmodules) +integer(C_LONG) :: i + +print*,'init dataset' + +numberofmodules=nmodules + +print*,'Number of modules:' +print*,numberofmodules +print*,'Channels per module:' +print*,chpmod + +totalnumberofchannels=nmodules*chpmod + +print*,'Total number of channels:' +print*,totalnumberofchannels + + +print*,'Modulemask:' +do i=1,nmodules + print*,i,modulemask(i) +enddo + +print*,'Badchannelmask:' +do i=1,nmodules*chpmod + print*,i,badchanmask(i) +enddo + +print*,'Flat field coefficients:' +do i=1,nmodules*chpmod + print*,i,ffcoeff(i),'+-',fferr(i) +enddo + +print*,'Tdead:' +print*,tdead + + +print*,'Angular conversion coefficients:' +do i=1,nmodules + print*,i,angradius(i),angoffset(i),angcenter(i) +enddo + + +print*,'Total offset:' +print*,totaloffset + +print*,'Bin size:' +print*,binsize + +numberofbins=360./binsize + + +print*,'Sample displacement:' +print*,samplex, sampley + +end subroutine initdataset + + + +subroutine resetdataset() bind(c, name='resetDataset') +IMPLICIT NONE + +print*,'reset dataset' + + +end subroutine resetdataset + + +subroutine finalizedataset(outang, outval, outerr, outnpoints) bind(c, name='finalize_dataset') +IMPLICIT NONE +integer(C_LONG), intent(OUT) :: outnpoints +real(C_DOUBLE), intent(OUT) :: outang(*), outval(*), outerr(*) +integer(C_LONG) :: i + +print*,'finalize dataset' + +outnpoints=numberofbins + +print*,'returning points:' +do i=1,numberofbins + + outang(i)=i; + outval(i)=i*100; + outerr(i)=i*0.1 + + print*,i,outang(i),outval(i),outerr(i) +enddo + +end subroutine finalizedataset + + + +subroutine addframe(data, pos, i0, exptime, fname, var) bind(c, name='add_frame') +IMPLICIT NONE +real(C_DOUBLE), intent(IN) :: data(totalnumberofchannels) +real(C_DOUBLE), intent(IN) :: pos, i0, exptime, var +character(kind=c_char), dimension(*), intent(IN) :: fname +integer :: l +integer :: i + +l=0 +do + if (fname(l+1) == C_NULL_CHAR) exit + l = l + 1 +end do + + +print*,'add frame' + +print*,'Filename: ' +print*,fname(1:l) + +print*,'Position: ' +print*,pos + +print*,'I0: ' +print*,i0 + +print*,'Exposure time: ' +print*,exptime + +print*,'Var: ' +print*,var + +print*,'Data: ' +print*,data + + +end subroutine addframe + + + +subroutine calculateflatfield(nmodules, chpmod, modulemask, badchanmask,data, ffcoeff,fferr) bind(c, name='calculate_flat_field') + +IMPLICIT NONE +integer(C_LONG), intent(IN) :: nmodules, chpmod +integer(C_LONG), intent(IN) :: modulemask(nmodules), badchanmask(nmodules*chpmod) +real(C_DOUBLE), intent(IN) :: data(nmodules*chpmod) +real(C_DOUBLE), intent(OUT) :: ffcoeff(*),fferr(*) +integer(C_LONG) :: i + +real(C_DOUBLE) :: ave; + +print*,'calculate flat field' + +do i=1,nmodules*chpmod + ffcoeff(i)=data(i)*10. + fferr(i)=i + print*,i,data(i), ffcoeff(i),fferr(i) +enddo + + + + +end subroutine calculateflatfield + + +end module ax diff --git a/slsDetectorSoftware/gitInfo.txt b/slsDetectorSoftware/gitInfo.txt new file mode 100644 index 000000000..6e76b64a9 --- /dev/null +++ b/slsDetectorSoftware/gitInfo.txt @@ -0,0 +1,9 @@ +Path: slsDetectorsPackage/slsDetectorSoftware +URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git +Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git +Repsitory UUID: 372aa91aaff8c6acd0fb70a257774ac56974a4b1 +Revision: 1154 +Branch: 2.1-rc +Last Changed Author: Dhanya_Maliakal +Last Changed Rev: 1154 +Last Changed Date: 2016-09-22 17:16:49 +0200 diff --git a/slsDetectorSoftware/gotthardDetectorServer/.target-makefrag b/slsDetectorSoftware/gotthardDetectorServer/.target-makefrag new file mode 100755 index 000000000..ce093ecac --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/.target-makefrag @@ -0,0 +1 @@ +AXIS_BUILDTYPE ?= cris-axis-linux-gnu diff --git a/slsDetectorSoftware/gotthardDetectorServer/Makefile b/slsDetectorSoftware/gotthardDetectorServer/Makefile new file mode 100755 index 000000000..a06a86180 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + + +CROSS = bfin-uclinux- +CC = $(CROSS)gcc + +CFLAGS += -Wall -DGOTTHARDD -DMCB_FUNCS -DDACS_INT -DDEBUG # -DVERBOSE #-DVERYVERBOSE #-DVIRTUAL #-DDACS_INT_CSERVER + + +PROGS= gotthardDetectorServer +INSTDIR= /tftpboot +INSTMODE= 0777 + + + +BINS = testlib_sharedlibc +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + + + +all: clean $(PROGS) + +boot: $(OBJS) + +$(PROGS): $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + + +romfs: + $(ROMFSINST) /bin/$(PROGS) + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/gotthardDetectorServer/Makefile.propix b/slsDetectorSoftware/gotthardDetectorServer/Makefile.propix new file mode 100755 index 000000000..6fb7a6207 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/Makefile.propix @@ -0,0 +1,48 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + + +CROSS = bfin-uclinux- +CC = $(CROSS)gcc + +CFLAGS += -Wall -DGOTTHARDD -DPROPIXD -DMCB_FUNCS -DDACS_INT -DDEBUG # -DVERBOSE #-DVERYVERBOSE #-DVIRTUAL #-DDACS_INT_CSERVER + + +PROGS= propixDetectorServer +INSTDIR= /tftpboot +INSTMODE= 0777 + + + +BINS = testlib_sharedlibc +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + + + +all: clean $(PROGS) + +boot: $(OBJS) + +$(PROGS): $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + + +romfs: + $(ROMFSINST) /bin/$(PROGS) + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/gotthardDetectorServer/Makefile.virtual b/slsDetectorSoftware/gotthardDetectorServer/Makefile.virtual new file mode 100755 index 000000000..4f563e2a0 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/Makefile.virtual @@ -0,0 +1,30 @@ + +DESTDIR ?= ./ + +CC = gcc +CFLAGS += -Wall -DGOTTHARDD -DMCB_FUNCS -DDACS_INT -DDEBUG -DVIRTUAL + + +PROGS= $(DESTDIR)/gotthardVirtualServer + + +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + +gotthardVirtualServer = $(PROGS) + +all: clean $(PROGS) + + +$(PROGS): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/gotthardDetectorServer/ansi.h b/slsDetectorSoftware/gotthardDetectorServer/ansi.h new file mode 120000 index 000000000..a122db0ad --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/ansi.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.c new file mode 120000 index 000000000..87a4f95d1 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.c @@ -0,0 +1 @@ +../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.h new file mode 120000 index 000000000..f220903b2 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/communication_funcs.h @@ -0,0 +1 @@ +../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c new file mode 100755 index 000000000..615427959 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.c @@ -0,0 +1,2425 @@ + +#include "server_defs.h" +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers_g.h" + +#ifdef SHAREDMEMORY +#include "sharedmemory.h" +#endif + +#include +#include +#include + +#include + +//for memory mapping +u_int64_t CSP0BASE; + +FILE *debugfp, *datafp; + +int fr; +int wait_time; +int *fifocntrl; + +//int *statusreg; commented out by dhanya +const int nModY=1; +int nModBoard; +int nModX=NMAXMOD; +int dynamicRange=16;//32; +int dataBytes=NMAXMOD*NCHIP*NCHAN*2; +int storeInRAM=0; +int ROI_flag=0; +int adcConfigured=-1; +u_int32_t *ram_values=NULL; +volatile char *now_ptr=NULL; +volatile u_int16_t *values; +int ram_size=0; + +int64_t totalTime=1; +u_int32_t progressMask=0; + +int phase_shift=DEFAULT_PHASE_SHIFT; +int ipPacketSize=DEFAULT_IP_PACKETSIZE; +int udpPacketSize=DEFAULT_UDP_PACKETSIZE; + + +int ififostart, ififostop, ififostep, ififo; + +int masterMode=NO_MASTER, syncMode=NO_SYNCHRONIZATION, timingMode=AUTO_TIMING; + +enum externalSignalFlag signals[4]={EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF}; + + +#ifdef MCB_FUNCS +extern const int nChans; +extern const int nChips; +//extern const int nDacs; +//extern const int nAdcs; +#endif +#ifndef MCB_FUNCS + +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +#endif + + + + +/** + ENEt conf structs +*/ +typedef struct mac_header_struct{ + u_int8_t mac_dest_mac2; + u_int8_t mac_dest_mac1; + u_int8_t mac_dummy1; + u_int8_t mac_dummy2; + u_int8_t mac_dest_mac6; + u_int8_t mac_dest_mac5; + u_int8_t mac_dest_mac4; + u_int8_t mac_dest_mac3; + u_int8_t mac_src_mac4; + u_int8_t mac_src_mac3; + u_int8_t mac_src_mac2; + u_int8_t mac_src_mac1; + u_int16_t mac_ether_type; + u_int8_t mac_src_mac6; + u_int8_t mac_src_mac5; +} mac_header; + +typedef struct ip_header_struct { + u_int16_t ip_len; + u_int8_t ip_tos; + u_int8_t ip_ihl:4 ,ip_ver:4; + u_int16_t ip_offset:13,ip_flag:3; + u_int16_t ip_ident; + u_int16_t ip_chksum; + u_int8_t ip_protocol; + u_int8_t ip_ttl; + u_int32_t ip_sourceip; + u_int32_t ip_destip; +} ip_header; + +typedef struct udp_header_struct{ + u_int16_t udp_destport; + u_int16_t udp_srcport; + u_int16_t udp_chksum; + u_int16_t udp_len; +} udp_header; + +typedef struct mac_conf_struct{ + mac_header mac; + ip_header ip; + udp_header udp; + u_int32_t npack; + u_int32_t lpack; + u_int32_t npad; + u_int32_t cdone; +} mac_conf; + +typedef struct tse_conf_struct{ + u_int32_t rev; //0x0 + u_int32_t scratch; + u_int32_t command_config; + u_int32_t mac_0; //0x3 + u_int32_t mac_1; + u_int32_t frm_length; + u_int32_t pause_quant; + u_int32_t rx_section_empty; //0x7 + u_int32_t rx_section_full; + u_int32_t tx_section_empty; + u_int32_t tx_section_full; + u_int32_t rx_almost_empty; //0xB + u_int32_t rx_almost_full; + u_int32_t tx_almost_empty; + u_int32_t tx_almost_full; + u_int32_t mdio_addr0; //0xF + u_int32_t mdio_addr1; +}tse_conf; + + + +int mapCSP0(void) { + printf("Mapping memory\n"); +#ifndef VIRTUAL + int fd; + fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + printf("\nCan't find /dev/mem!\n"); + return FAIL; + } + printf("/dev/mem opened\n"); + + CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + printf("\nCan't map memmory area!!\n"); + return FAIL; + } + printf("CSP0 mapped\n"); + +#endif +#ifdef VIRTUAL + CSP0BASE = malloc(MEM_SIZE); + printf("memory allocated\n"); +#endif +#ifdef SHAREDMEMORY + if ( (res=inism(SMSV))<0) { + printf("error attaching shared memory! %i",res); + return FAIL; + } +#endif + printf("CSPObase is 0x%x \n",CSP0BASE); + printf("CSPOBASE=from %08x to %x\n",CSP0BASE,CSP0BASE+MEM_SIZE); + + u_int32_t address; + address = FIFO_DATA_REG_OFF; + values=(u_int16_t*)(CSP0BASE+address*2); + printf("statusreg=%08x\n",bus_r(STATUS_REG)); + printf("\n\n"); + return OK; +} + +u_int16_t bus_r16(u_int32_t offset){ + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + return *ptr1; +} + +u_int16_t bus_w16(u_int32_t offset, u_int16_t data) { + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + *ptr1=data; + return OK; +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_w16(u_int32_t ramType, int adc, int adcCh, int Ch, u_int16_t data) { + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Writing to addr:%x\n",adr); + return bus_w16(adr,data); +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_r16(u_int32_t ramType, int adc, int adcCh, int Ch){ + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Reading from addr:%x\n",adr); + return bus_r16(adr); +} + +u_int32_t bus_w(u_int32_t offset, u_int32_t data) { + volatile u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + *ptr1=data; + + return OK; +} + + +u_int32_t bus_r(u_int32_t offset) { + volatile u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + return *ptr1; +} + + +int setPhaseShiftOnce(){ + u_int32_t addr, reg; + int i; + addr=MULTI_PURPOSE_REG; + reg=bus_r(addr); +#ifdef VERBOSE + printf("Multipurpose reg:%x\n",reg); +#endif + + //Checking if it is power on(negative number) + // if(((reg&0xFFFF0000)>>16)>0){ + //bus_w(addr,0x0); //clear the reg + + if(reg==0){ + printf("\nImplementing phase shift of %d\n",phase_shift); + for (i=1;i=0 && d<4) { + signals[d]=mode; +#ifdef VERBOSE + printf("settings signal variable number %d to value %04x\n", d, signals[d]); +#endif + + // if output signal, set it! + + switch (mode) { + case GATE_IN_ACTIVE_HIGH: + case GATE_IN_ACTIVE_LOW: + if (timingMode==GATE_FIX_NUMBER || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case TRIGGER_IN_RISING_EDGE: + case TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_EXPOSURE || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case RO_TRIGGER_IN_RISING_EDGE: + case RO_TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_READOUT) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case MASTER_SLAVE_SYNCHRONIZATION: + setSynchronization(syncMode); + break; + default: + setFPGASignal(d,mode); + break; + } + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + } + + +// if (mode<=RO_TRIGGER_OUT_FALLING_EDGE && mode>=0) +// bus_w(EXT_SIGNAL_REG,((modes[mode])<=0) { +#ifdef VERBOSE + printf("writing signal register number %d mode %04x\n",d, modes[mode]); +#endif + bus_w(EXT_SIGNAL_REG,((modes[mode])<>off); + + if (mode=0 && d<4) { +#ifdef VERBOSE + printf("gettings signal variable number %d value %04x\n", d, signals[d]); +#endif + return signals[d]; + } else + return -1; + + +} + + +int getFPGASignal(int d) { + + int modes[]={SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW,TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE,RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE,RO_TRIGGER_OUT_FALLING_EDGE}; + + int off=d*SIGNAL_OFFSET; + int mode=((bus_r(EXT_SIGNAL_REG)&(SIGNAL_MASK<>off); + + if (mode<=RO_TRIGGER_OUT_FALLING_EDGE) { + if (modes[mode]!=SIGNAL_OFF && signals[d]!=MASTER_SLAVE_SYNCHRONIZATION) + signals[d]=modes[mode]; +#ifdef VERYVERBOSE + printf("gettings signal register number %d value %04x\n", d, modes[mode]); +#endif + return modes[mode]; + } else + return -1; + +} + + + + + +/* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; +*/ + + +int setTiming(int ti) { + + + int ret=GET_EXTERNAL_COMMUNICATION_MODE; + + int g=-1, t=-1, rot=-1; + + int i; + + switch (ti) { + case AUTO_TIMING: + timingMode=ti; + // disable all gates/triggers in except if used for master/slave synchronization + for (i=0; i<4; i++) { + if (getFPGASignal(i)>0 && getFPGASignal(i)=0 && t>=0 && rot<0) { + ret=GATE_WITH_START_TRIGGER; + } else if (g<0 && t>=0 && rot<0) { + ret=TRIGGER_EXPOSURE; + } else if (g>=0 && t<0 && rot<0) { + ret=GATE_FIX_NUMBER; + } else if (g<0 && t<0 && rot>0) { + ret=TRIGGER_READOUT; + } else if (g<0 && t<0 && rot<0) { + ret=AUTO_TIMING; + } + + // timingMode=ret; + + return ret; + +} + + + +int setConfigurationRegister(int d) { +#ifdef VERBOSE + printf("Setting configuration register to %x",d); +#endif + if (d>=0) { + bus_w(CONFIG_REG,d); + } +#ifdef VERBOSE + printf("configuration register is %x", bus_r(CONFIG_REG)); +#endif + return bus_r(CONFIG_REG); +} + +int setToT(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting ToT to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: ToT is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|TOT_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~TOT_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("ToT is %x\n", reg); +#endif + if (reg&TOT_ENABLE_BIT) + return 1; + else + return 0; +} + +int setContinousReadOut(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting Continous readout to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: Continous readout is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|CONT_RO_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~CONT_RO_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Continous readout is %x\n", reg); +#endif + if (reg&CONT_RO_ENABLE_BIT) + return 1; + else + return 0; +} + + +int startReceiver(int start) { + u_int32_t addr=CONFIG_REG; +#ifdef VERBOSE + if(start) + printf("Setting up detector to send to Receiver\n"); + else + printf("Setting up detector to send to CPU\n"); +#endif + int reg=bus_r(addr); + //for start recever, write 0 and for stop, write 1 + if (!start) + bus_w(CONFIG_REG,reg|CPU_OR_RECEIVER_BIT); + else + bus_w(CONFIG_REG,reg&(~CPU_OR_RECEIVER_BIT)); + + reg=bus_r(addr); +//#ifdef VERBOSE + printf("Config Reg %x\n", reg); +//#endif + int d =reg&CPU_OR_RECEIVER_BIT; + if(d!=0) d=1; + if(d!=start) + return OK; + else + return FAIL; +} + + +u_int64_t getDetectorNumber() { + char output[255],mac[255]=""; + u_int64_t res=0; + FILE* sysFile = popen("ifconfig eth0 | grep HWaddr | cut -d \" \" -f 11", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + //getting rid of ":" + char * pch; + pch = strtok (output,":"); + while (pch != NULL){ + strcat(mac,pch); + pch = strtok (NULL, ":"); + } + sscanf(mac,"%llx",&res); + return res; +} + +u_int32_t getFirmwareVersion() { + return bus_r(FPGA_VERSION_REG); +} + +u_int32_t getFirmwareSVNVersion(){ + return bus_r(FPGA_SVN_REG); +} + + +// for fpga test +u_int32_t testFpga(void) { + printf("Testing FPGA:\n"); + volatile u_int32_t val,addr,val2; + int result=OK,i; + //fixed pattern + val=bus_r(FIX_PATT_REG); + if (val==FIXED_PATT_VAL) { + printf("fixed pattern ok!! %08x\n",val); + } else { + printf("fixed pattern wrong!! %08x\n",val); + result=FAIL; + } + + //dummy register + addr = DUMMY_REG; + for(i=0;i<1000000;i++) + { + val=0x5A5A5A5A-i; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x5A5A5A5A-i) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of %x \n",i,val,0x5A5A5A5A-i); + result=FAIL; + } + val=(i+(i<<10)+(i<<20)); + bus_w(addr, val); + val2=bus_r(addr); + if (val2!=val) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! read %x instead of %x.\n",i,val2,val); + result=FAIL; + } + val=0x0F0F0F0F; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x0F0F0F0F) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0x0F0F0F0F \n",i,val); + result=FAIL; + } + val=0xF0F0F0F0; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0xF0F0F0F0) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0xF0F0F0F0 \n\n",i,val); + result=FAIL; + } + } + if(result==OK) + { + printf("----------------------------------------------------------------------------------------------"); + printf("\nATTEMPT 1000000: FPGA DUMMY REGISTER OK!!!\n"); + printf("----------------------------------------------------------------------------------------------"); + } + printf("\n"); + return result; +} + + +// for fpga test +u_int32_t testRAM(void) { + int result=OK; + int i=0; + allocateRAM(); + // while(i<100000) { + memcpy(ram_values, values, dataBytes); + printf ("Testing RAM:\t%d: copied fifo %x to memory %x size %d\n",i++, (unsigned int)(values), (unsigned int)(ram_values), dataBytes); + // } + return result; +} + +int getNModBoard() { + return nModX; +} + +int setNMod(int n) { + return nModX; +} + + +// fifo test +int testFifos(void) { + printf("Fifo test not implemented!\n"); + bus_w16(CONTROL_REG, START_FIFOTEST_BIT); + bus_w16(CONTROL_REG, 0x0); + return OK; +} + + + +// program dacq settings + +int64_t set64BitReg(int64_t value, int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + if (value!=-1) { + vLSB=value&(0xffffffff); + bus_w(aLSB,vLSB); + v64=value>> 32; + vMSB=v64&(0xffffffff); + bus_w(aMSB,vMSB); + } + return get64BitReg(aLSB, aMSB); + +} + +int64_t get64BitReg(int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + vLSB=bus_r(aLSB); + vMSB=bus_r(aMSB); + v64=vMSB; + v64=(v64<<32) | vLSB; + return v64; +} + +int64_t setFrames(int64_t value){ + return set64BitReg(value, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); +} + +int64_t getFrames(){ + return get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); +} + +int64_t setExposureTime(int64_t value){ + /* time is in ns */ + if (value!=-1) + value*=(1E-9*CLK_FREQ); + return set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getExposureTime(){ + return get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setGates(int64_t value){ + return set64BitReg(value, SET_GATES_LSB_REG, SET_GATES_MSB_REG); +} + +int64_t getGates(){ + return get64BitReg(GET_GATES_LSB_REG, GET_GATES_MSB_REG); +} + +int64_t setPeriod(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + + + + return set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getPeriod(){ + return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setDelay(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + return set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getDelay(){ + return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setTrains(int64_t value){ + return set64BitReg(value, SET_TRAINS_LSB_REG, SET_TRAINS_MSB_REG); +} + +int64_t getTrains(){ + return get64BitReg(GET_TRAINS_LSB_REG, GET_TRAINS_MSB_REG); +} + + +int64_t setProbes(int64_t value){ + return 0; +} + + +int64_t setProgress() { + + //????? eventually call after setting the registers + +return 0; + +} + + +int64_t getProgress() { + + + //should be done in firmware!!!! + + return 0; + +} + +int64_t getActualTime(){ + return get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getMeasurementTime(){ + int64_t v=get64BitReg(GET_MEASUREMENT_TIME_LSB_REG, GET_MEASUREMENT_TIME_MSB_REG); + int64_t mask=0x8000000000000000; + if (v & mask ) { +#ifdef VERBOSE + printf("no measurement time left\n"); +#endif + return -1E+9; + } else + return v/(1E-9*CLK_FREQ); +} + + + + +int loadImage(int index, short int ImageVals[]){ + u_int32_t address; + switch (index) { + case DARK_IMAGE : + address = DARK_IMAGE_REG; + break; + case GAIN_IMAGE : + address = GAIN_IMAGE_REG; + break; + } + volatile u_int16_t *ptr; + ptr=(u_int16_t*)(CSP0BASE+address*2); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,ImageVals[i]); +#endif + memcpy(ptr,ImageVals ,dataBytes); +#ifdef VERBOSE + printf("\nLoaded x%08x address with image of index %d\n",(unsigned int)(ptr),index); +#endif + return OK; +} + + + +int64_t getProbes(){ + return 0; +} + + +int setDACRegister(int idac, int val, int imod) { + u_int32_t addr, reg, mask; + int off; +#ifdef VERBOSE + if(val==-1) + printf("Getting dac register%d module %d\n",idac,imod); + else + printf("Setting dac register %d module %d to %d\n",idac,imod,val); +#endif + + switch(idac){ + case 0: + case 1: + case 2: + addr=MOD_DACS1_REG; + break; + case 3: + case 4: + case 5: + addr=MOD_DACS2_REG; + break; + case 6: + case 7: + addr=MOD_DACS3_REG; + break; + default: + printf("weird idac value %d\n",idac); + return -1; + break; + } + //saving only the msb + val=val>>2; + + off=(idac%3)*10; + mask=~((0x3ff)<=0 && val>off)&0x3ff; + //since we saved only the msb + val=val<<2; + + //val=(bus_r(addr)>>off)&0x3ff; + + +#ifdef VERBOSE + printf("Dac %d module %d register is %d\n\n",idac,imod,val); +#endif + return val; +} + + +int getTemperature(int tempSensor, int imod){ + int val; + imod=0;//ignoring more than 1 mod for now + int i,j,repeats=6; + u_int32_t tempVal=0; +#ifdef VERBOSE + char cTempSensor[2][100]={"ADCs/ASICs","VRs/FPGAs"}; + printf("Getting Temperature of module:%d for the %s for tempsensor:%d\n",imod,cTempSensor[tempSensor],tempSensor); +#endif + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + bus_w(TEMP_IN_REG,((T1_CLK_BIT)&~(T1_CS_BIT))|(T2_CLK_BIT));//high clk low cs + + for(i=0;i<20;i++) { + //repeats is number of register writes for delay + for(j=0;j>1);//fpga + } + } + + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + val=((int)tempVal)/4.0; + +#ifdef VERBOSE + printf("Temperature of module:%d for the %s is %.2fC\n",imod,cTempSensor[tempSensor],val); +#endif + return val; +} + + + +int initHighVoltage(int val, int imod){ +#ifdef VERBOSE + printf("Setting/Getting High Voltage of module:%d with val:%d\n",imod,val); +#endif + volatile u_int32_t addr=HV_REG; + int writeVal,writeVal2; + switch(val){ + case -1: break; + case 0: writeVal=0x0; writeVal2=0x0; break; + case 90: writeVal=0x0; writeVal2=0x1; break; + case 110:writeVal=0x2; writeVal2=0x3; break; + case 120:writeVal=0x4; writeVal2=0x5; break; + case 150:writeVal=0x6; writeVal2=0x7; break; + case 180:writeVal=0x8; writeVal2=0x9; break; + case 200:writeVal=0xA; writeVal2=0xB; break; + default :printf("Invalid voltage\n");return -2;break; + } + //to set value + if(val!=-1){ + //set value to converted value + bus_w(addr,writeVal); + bus_w(addr,writeVal2); +#ifdef VERBOSE + printf("Value sent is %d and then %d\n",writeVal,writeVal2); +#endif + } + //read value and return the converted value + val=bus_r(addr); +#ifdef VERBOSE + printf("Value read from reg is %d\n",val); +#endif + switch(val){ + case 0x0:val=0;break; + case 0x1:val=90;break; + case 0x3:val=110;break; + case 0x5:val=120;break; + case 0x7:val=150;break; + case 0x9:val=180;break; + case 0xB:val=200;break; + default:printf("Weird value read:%d\n",val);return -3;break; + } +#ifdef VERBOSE + printf("High voltage of module:%d is %d\n",imod,val); +#endif + return val; +} + + + +int initConfGain(int isettings,int val,int imod){ + int retval; + u_int32_t addr=GAIN_REG; + + if(val!=-1){ +#ifdef VERBOSE + printf("Setting Gain of module:%d with val:%d\n",imod,val); +#endif + bus_w(addr,((val<>SETTINGS_OFFSET); +#ifdef VERBOSE + printf("Settings read from reg is %d\n",retval); +#endif + if((isettings!=-1)&&(retval!=isettings)){ + printf("\n\nSettings r\n\n"); + return -1; + } + + return retval; +} + + + +int setADC(int adc){ + int reg,nchips,mask; + + if(adc==-1) ROI_flag=0; + else ROI_flag=1; + + setDAQRegister();//token timing + cleanFifo();//adc sync + + //all adc + if(adc==-1){ + //set packet size + ipPacketSize= DEFAULT_IP_PACKETSIZE; + udpPacketSize=DEFAULT_UDP_PACKETSIZE; + //set channel mask + nchips = NCHIP; + mask = ACTIVE_ADC_MASK; + } + //1 adc + else{ + ipPacketSize= ADC1_IP_PACKETSIZE; + udpPacketSize=ADC1_UDP_PACKETSIZE; + //set channel mask + nchips = NCHIPS_PER_ADC; + mask = 1<mac.mac_dest_mac1 =((macad>>(8*5))&0xFF);// 0x00; //pc7060 + mac_conf_regs->mac.mac_dest_mac2 =((macad>>(8*4))&0xFF);// 0x19; //pc7060 + mac_conf_regs->mac.mac_dest_mac3 =((macad>>(8*3))&0xFF);// 0x99; //pc7060 + mac_conf_regs->mac.mac_dest_mac4 =((macad>>(8*2))&0xFF);// 0x24; //pc7060 + mac_conf_regs->mac.mac_dest_mac5 =((macad>>(8*1))&0xFF);// 0xEB; //pc7060 + mac_conf_regs->mac.mac_dest_mac6 =((macad>>(8*0))&0xFF);// 0xEE; //pc7060 + /* + mac_conf_regs->mac.mac_src_mac1 = 0x00; + mac_conf_regs->mac.mac_src_mac2 = 0xAA; + mac_conf_regs->mac.mac_src_mac3 = 0xBB; + mac_conf_regs->mac.mac_src_mac4 = 0xCC; + mac_conf_regs->mac.mac_src_mac5 = 0xDD; + mac_conf_regs->mac.mac_src_mac6 = 0xEE; + */ + mac_conf_regs->mac.mac_src_mac1 =((detectormacad>>(8*5))&0xFF); + mac_conf_regs->mac.mac_src_mac2 =((detectormacad>>(8*4))&0xFF); + mac_conf_regs->mac.mac_src_mac3 =((detectormacad>>(8*3))&0xFF); + mac_conf_regs->mac.mac_src_mac4 =((detectormacad>>(8*2))&0xFF); + mac_conf_regs->mac.mac_src_mac5 =((detectormacad>>(8*1))&0xFF); + mac_conf_regs->mac.mac_src_mac6 =((detectormacad>>(8*0))&0xFF); + mac_conf_regs->mac.mac_ether_type = 0x0800; //ipv4 + + + mac_conf_regs->ip.ip_ver = 0x4; + mac_conf_regs->ip.ip_ihl = 0x5; + mac_conf_regs->ip.ip_tos = 0x0; + mac_conf_regs->ip.ip_len = ipPacketSize;//0x0522; // was 0x0526; + mac_conf_regs->ip.ip_ident = 0x0000; + mac_conf_regs->ip.ip_flag = 0x2; + mac_conf_regs->ip.ip_offset = 0x00; + mac_conf_regs->ip.ip_ttl = 0x70; + mac_conf_regs->ip.ip_protocol = 0x11; + mac_conf_regs->ip.ip_chksum = 0x0000 ; //6E42 now is automatically computed + mac_conf_regs->ip.ip_sourceip = detipad; //0x8181CA2E;129.129.202.46 + mac_conf_regs->ip.ip_destip = ipad; //CA57 + +#ifdef VERBOSE + printf("mac_dest:%llx %x:%x:%x:%x:%x:%x\n", + macad, + mac_conf_regs->mac.mac_dest_mac1, + mac_conf_regs->mac.mac_dest_mac2, + mac_conf_regs->mac.mac_dest_mac3, + mac_conf_regs->mac.mac_dest_mac4, + mac_conf_regs->mac.mac_dest_mac5, + mac_conf_regs->mac.mac_dest_mac6); + printf("mac_src:%llx %x:%x:%x:%x:%x:%x\n", + detectormacad, + mac_conf_regs->mac.mac_src_mac1, + mac_conf_regs->mac.mac_src_mac2, + mac_conf_regs->mac.mac_src_mac3, + mac_conf_regs->mac.mac_src_mac4, + mac_conf_regs->mac.mac_src_mac5, + mac_conf_regs->mac.mac_src_mac6); + printf("ip_ttl:%x\n",mac_conf_regs->ip.ip_ttl); +#endif + + //checksum + count=sizeof(mac_conf_regs->ip); + addr=&(mac_conf_regs->ip); + while( count > 1 ) { + sum += *addr++; + count -= 2; + } + if( count > 0 ) sum += *addr; // Add left-over byte, if any + while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);// Fold 32-bit sum to 16 bits + checksum = (~sum)&0xffff; + mac_conf_regs->ip.ip_chksum = checksum; + //#ifdef VERBOSE + printf("IP header checksum is 0x%x s\n",(unsigned int)(checksum)); + //#endif + + mac_conf_regs->udp.udp_srcport = 0xE185; + mac_conf_regs->udp.udp_destport = udpport;//0xC351; + mac_conf_regs->udp.udp_len = udpPacketSize;//0x050E; //was 0x0512; + mac_conf_regs->udp.udp_chksum = 0x0000; + +#ifdef VERBOSE + printf("Configuring TSE\n"); +#endif + tse_conf_regs->rev = 0xA00; + tse_conf_regs->scratch = 0xCCCCCCCC; + tse_conf_regs->command_config = 0xB; + tse_conf_regs->mac_0 = 0x17231C00; + tse_conf_regs->mac_1 = 0xCB4A; + tse_conf_regs->frm_length = 0x5DC; //max frame length (1500 bytes) (was 0x41C) + tse_conf_regs->pause_quant = 0x0; + tse_conf_regs->rx_section_empty = 0x7F0; + tse_conf_regs->rx_section_full = 0x10; + tse_conf_regs->tx_section_empty = 0x3F8; //was 0x7F0; + tse_conf_regs->tx_section_full = 0x16; + tse_conf_regs->rx_almost_empty = 0x8; + tse_conf_regs->rx_almost_full = 0x8; + tse_conf_regs->tx_almost_empty = 0x8; + tse_conf_regs->tx_almost_full = 0x3; + tse_conf_regs->mdio_addr0 = 0x12; + tse_conf_regs->mdio_addr1 = 0x0; + mac_conf_regs->cdone = 0xFFFFFFFF; + + + if(ival) + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|WRITE_BACK_BIT|DIGITAL_TEST_BIT)); //0x2840,write shadow regs.. + else + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|WRITE_BACK_BIT)); //0x2840,write shadow regs.. + + val=bus_r(addrr); +#ifdef VERBOSE + printf("Value read from Multi-purpose Reg:%x\n",val); +#endif + // if(val!=0x2840) return -1; + + usleep(100000); + + if(ival) + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|SW1_BIT|DIGITAL_TEST_BIT)); //0x2820,write shadow regs.. + else + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|SW1_BIT)); //0x2820,write shadow regs.. + + val=bus_r(addrr); +#ifdef VERBOSE + printf("Value read from Multi-purpose Reg:%x\n",val); +#endif + // if(val!=0x2820) return -1; + + + return adcConfigured; +} + + +int getAdcConfigured(){ + return adcConfigured; +} + +u_int32_t runBusy(void) { + u_int32_t s = bus_r(STATUS_REG); + return s; +} + +u_int32_t dataPresent(void) { + return bus_r(LOOK_AT_ME_REG); +} + +u_int32_t runState(void) { + int s=bus_r(STATUS_REG); +#ifdef SHAREDMEMORY + if (s&RUN_BUSY_BIT) + write_status_sm("Running"); + else + write_status_sm("Stopped"); +#endif +#ifdef VERBOSE + printf("status %04x\n",s); +#endif + +/* if (s==0x62001) + exit(-1);*/ + return s; +} + + +// State Machine + +int startStateMachine(){ + +//#ifdef VERBOSE + printf("*******Starting State Machine*******\n"); +//#endif + cleanFifo(); + // fifoReset(); + now_ptr=(char*)ram_values; +#ifdef SHAREDMEMORY + write_stop_sm(0); + write_status_sm("Started"); +#endif + bus_w16(CONTROL_REG, START_ACQ_BIT | START_EXPOSURE_BIT); + bus_w16(CONTROL_REG, 0x0); + printf("statusreg=%08x\n",bus_r(STATUS_REG)); + return OK; +} + + + + +int stopStateMachine(){ + +//#ifdef VERBOSE + printf("*******Stopping State Machine*******\n"); +//#endif +#ifdef SHAREDMEMORY + write_stop_sm(1); + write_status_sm("Stopped"); +#endif + bus_w16(CONTROL_REG, STOP_ACQ_BIT); + bus_w16(CONTROL_REG, 0x0); + usleep(500); + // if (!runBusy()) + if(!(bus_r(STATUS_REG)&RUNMACHINE_BUSY_BIT)) + return OK; + else + return FAIL; +} + + +int startReadOut(){ + u_int32_t status; +#ifdef VERBOSE + printf("Starting State Machine Readout\n"); +#endif + status=bus_r(STATUS_REG)&RUN_BUSY_BIT; +#ifdef DEBUG + printf("State machine status is %08x\n",bus_r(STATUS_REG)); +#endif + bus_w16(CONTROL_REG, START_ACQ_BIT |START_READOUT_BIT); // start readout + bus_w16(CONTROL_REG, 0x0); + return OK; +} + + +// fifo routines + +u_int32_t fifoReset(void) { + return -1; +} + + +u_int32_t setNBits(u_int32_t n) { + return -1; +} + +u_int32_t getNBits(){ + return -1; +} + + +u_int32_t fifoReadCounter(int fifonum){ + return -1; +} + +u_int32_t fifoReadStatus() +{ + // reads from the global status register + + return bus_r(STATUS_REG)&(SOME_FIFO_FULL_BIT | ALL_FIFO_EMPTY_BIT); +} + +u_int32_t fifo_full(void) +{ + // checks fifo empty flag returns 1 if fifo is empty + // otherwise 0 + return bus_r(STATUS_REG)&SOME_FIFO_FULL_BIT; +} + + +u_int32_t* fifo_read_event() +{ +#ifdef VIRTUAL + return NULL; +#endif + +#ifdef VERBOSE + printf("before looping\n"); +#endif + volatile u_int32_t t = bus_r(LOOK_AT_ME_REG); + +#ifdef VERBOSE + printf("lookatmereg=x%x\n",t); +#endif +/* + while ((t&0x1)==0) + { + t = bus_r(LOOK_AT_ME_REG); + if (!runBusy()){ + return NULL; + } + } +*/ + + while((t&0x1)==0) { + if (runBusy()==0) { + t = bus_r(LOOK_AT_ME_REG); + if ((t&0x1)==0) { +#ifdef VERBOSE + printf("no frame found - exiting "); + printf("%08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); +#endif + return NULL; + } else { +#ifdef VERBOSE + printf("no frame found %x status %x\n", bus_r(LOOK_AT_ME_REG),runState()); +#endif + break; + } + } + t = bus_r(LOOK_AT_ME_REG); + } + + +#ifdef VERBOSE + printf("before readout %08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); +#endif + + dma_memcpy(now_ptr,values ,dataBytes); + + +#ifdef VERYVERBOSE + int a; + for (a=0;a<8; a=a+2) + printf("\n%d %d: x%04x x%04x ",a+1,a,*(now_ptr+a+1),*(now_ptr+a) ); + for (a=2554;a<2560; a=a+2) + printf("\n%d %d: x%04x x%04x ",a+1,a,*(now_ptr+a+1),*(now_ptr+a) ); + printf("********\n"); + //memcpy(now_ptr, values, dataBytes); +#endif +#ifdef VERBOSE + printf("Copying to ptr %08x %d\n",(unsigned int)(now_ptr), dataBytes); + printf("after readout %08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); +#endif + + if (storeInRAM>0) { + now_ptr+=dataBytes; + } + return ram_values; +} + + + +u_int32_t* decode_data(int *datain) +{ + u_int32_t *dataout; + // const char one=1; + const int bytesize=8; + char *ptr=(char*)datain; + //int nbits=dynamicRange; + int ipos=0, ichan=0;; + //int nch, boff=0; + int ibyte;//, ibit; + char iptr; + +#ifdef VERBOSE + printf("Decoding data for DR %d\n",dynamicRange); +#endif + dataout=malloc(nChans*nChips*nModX*4); + ichan=0; + switch (dynamicRange) { + case 1: + for (ibyte=0; ibyte>(ipos))&0x1; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibyte>(ipos*4))&0xf; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichan0) + storeInRAM=1; + else + storeInRAM=0; + return allocateRAM(); +} + + +int allocateRAM() { + size_t size; + u_int32_t nt, nf; + nt=setTrains(-1); + nf=setFrames(-1); + if (nt==0) nt=1; + if (nf==0) nf=1; + // ret=clearRAM(); + if (storeInRAM) { + size=dataBytes*nf*nt; + if (size>(23-i))&0x1)<>(23-i))&0x1)<>(23-i))&0x1)<>(23-i))&0x1)<> 8); + // printf("%i: %i %i\n",a, frame[a],v); + avg[a] += ((double)frame[a])/(double)frames; + //if(frame[a] == 8191) + // printf("ch %i: %u\n",a,frame[a]); + } + // printf("********\n"); + numberFrames++; + } + + //no more data or no data + else { + if(getFrames()>-2) { + dataret=FAIL; + printf("no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + + } else { + dataret=FINISHED; + printf("acquisition successfully finished\n"); + + } + printf("dataret %d\n",dataret); + } + } + + + + double nf = (double)numberFrames; + for(i =0; i < 1280; i++){ + adc = i / 256; + adcCh = (i - adc * 256) / 32; + Ch = i - adc * 256 - adcCh * 32; + adc--; + double v2 = avg[i]; + avg[i] = avg[i]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[i]; + printf("setting avg for channel %i(%i,%i,%i): %i (double= %f (%f))\t", i,adc,adcCh,Ch, v,avg[i],v2); + v=i*100; + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + + /*for(adc = 1; adc < 5; adc++){ + for(adcCh = 0; adcCh < 8; adcCh++){ + for(Ch=0 ; Ch < 32; Ch++){ + int channel = (adc+1) * 32 * 8 + adcCh * 32 + Ch; + double v2 = avg[channel]; + avg[channel] = avg[channel]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[channel]; + printf("setting avg for channel %i: %i (double= %f (%f))\t", channel, v,avg[channel],v2); + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + } + }*/ + + + + printf("frames: %i\n",numberFrames); + printf("corrected avg by: %f\n",(double)numberFrames/(double)frames); + + printf("restoring previous condition\n"); + setFrames(framesBefore); + setPeriod(periodBefore); + + printf("---------------------------\n"); + return 0; +} + diff --git a/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.h new file mode 100755 index 000000000..975342e92 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/firmware_funcs.h @@ -0,0 +1,177 @@ +#ifndef FIRMWARE_FUNCS_H +#define FIRMWARE_FUNCS_H + + +#include "sls_detector_defs.h" + + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +int mapCSP0(void); + +u_int16_t bus_r16(u_int32_t offset); +u_int16_t bus_w16(u_int32_t offset, u_int16_t data);//aldos function +u_int32_t bus_w(u_int32_t offset, u_int32_t data); +u_int32_t bus_r(u_int32_t offset); + +int setPhaseShiftOnce(); +int cleanFifo(); +int setDAQRegister(); + +u_int32_t putout(char *s, int modnum); +u_int32_t readin(int modnum); +u_int32_t setClockDivider(int d); +u_int32_t getClockDivider(); +u_int32_t setSetLength(int d); +u_int32_t getSetLength(); +u_int32_t setWaitStates(int d); +u_int32_t getWaitStates(); +u_int32_t setTotClockDivider(int d); +u_int32_t getTotClockDivider(); +u_int32_t setTotDutyCycle(int d); +u_int32_t getTotDutyCycle(); + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode); +int getExtSignal(int d); + +u_int32_t setFPGASignal(int d, enum externalSignalFlag mode); +int getFPGASignal(int d); + +int setTiming(int t); + + +int setConfigurationRegister(int d); +int setToT(int d); +int setContinousReadOut(int d); +int startReceiver(int d); + +int setDACRegister(int idac, int val, int imod); + +int getTemperature(int tempSensor,int imod); +int initHighVoltage(int val,int imod); +int initConfGain(int isettings,int val,int imod); + +int setADC(int adc); +int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int ival, int udpport); +int getAdcConfigured(); + + +u_int64_t getDetectorNumber(); +u_int32_t getFirmwareVersion(); +int testFifos(void); +u_int32_t testFpga(void); +u_int32_t testRAM(void); +int testBus(void); +int setDigitalTestBit(int ival); + +int64_t set64BitReg(int64_t value, int aLSB, int aMSB); +int64_t get64BitReg(int aLSB, int aMSB); + +int64_t setFrames(int64_t value); +int64_t getFrames(); + +int64_t setExposureTime(int64_t value); +int64_t getExposureTime(); + +int64_t setGates(int64_t value); +int64_t getGates(); + +int64_t setDelay(int64_t value); +int64_t getDelay(); + +int64_t setPeriod(int64_t value); +int64_t getPeriod(); + +int64_t setTrains(int64_t value); +int64_t getTrains(); + +int64_t setProbes(int64_t value); +int64_t getProbes(); + +int64_t getProgress(); +int64_t setProgress(); + +int64_t getActualTime(); +int64_t getMeasurementTime(); + + +u_int32_t runBusy(void); +u_int32_t runState(void); +u_int32_t dataPresent(void); + + +int startStateMachine(); +int stopStateMachine(); +int startReadOut(); +u_int32_t fifoReset(void); +u_int32_t fifoReadCounter(int fifonum); +u_int32_t fifoReadStatus(); + + +u_int32_t fifo_full(void); + + + +u_int32_t* fifo_read_event(); +u_int32_t* decode_data(int* datain); +//u_int32_t move_data(u_int64_t* datain, u_int64_t* dataout); +int setDynamicRange(int dr); +int getDynamicRange(); +int getNModBoard(); +int setNMod(int n); +int setStoreInRAM(int b); +int allocateRAM(); +int clearRAM(); + + +int setMaster(int f); +int setSynchronization(int s); + +int loadImage(int index, short int ImageVals[]); +int readCounterBlock(int startACQ, short int CounterVals[]); +int resetCounterBlock(int startACQ); + +int calibratePedestal(int frames); + + + +/* + +u_int32_t setNBits(u_int32_t); +u_int32_t getNBits(); +*/ + +/* +//move to mcb_funcs? + +int readOutChan(int *val); +u_int32_t getModuleNumber(int modnum); +int testShiftIn(int imod); +int testShiftOut(int imod); +int testShiftStSel(int imod); +int testDataInOut(int num, int imod); +int testExtPulse(int imod); +int testExtPulseMux(int imod, int ow); +int testDataInOutMux(int imod, int ow, int num); +int testOutMux(int imod); +int testFpgaMux(int imod); +int calibration_sensor(int num, int *values, int *dacs) ; +int calibration_chip(int num, int *values, int *dacs); +*/ + + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt b/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt new file mode 100644 index 000000000..48cd8d11c --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/gitInfo.txt @@ -0,0 +1,9 @@ +Path: slsDetectorsPackage/slsDetectorSoftware/gotthardDetectorServer +URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git/gotthardDetectorServer +Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git +Repsitory UUID: 8aceb5d4b0ca6bd95a11b53e7a799b463b92d51b +Revision: 197 +Branch: developer +Last Changed Author: Dhanya_Maliakal +Last Changed Rev: 334 +Last Changed Date: 2016-08-12 11:08:03 +0200 diff --git a/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h new file mode 100644 index 000000000..b7bf78fa2 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthard.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "git@git.psi.ch:sls_detectors_software/sls_detector_software.git/gotthardDetectorServer" +//#define SVNREPPATH "" +#define SVNREPUUID "8aceb5d4b0ca6bd95a11b53e7a799b463b92d51b" +//#define SVNREV 0x334 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "Dhanya_Maliakal" +#define SVNREV 0x334 +#define SVNDATE 0x20160812 +// diff --git a/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthardTmp.h b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthardTmp.h new file mode 100644 index 000000000..58e48f497 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/gitInfoGotthardTmp.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "" +//#define SVNREPPATH "" +#define SVNREPUUID "" +//#define SVNREV "" +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "" +#define SVNREV "" +#define SVNDATE "" +// diff --git a/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv2.0.3 b/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv2.0.3 new file mode 100755 index 000000000..d6d9b460e Binary files /dev/null and b/slsDetectorSoftware/gotthardDetectorServer/gotthardDetectorServerv2.0.3 differ diff --git a/slsDetectorSoftware/gotthardDetectorServer/gotthardVirtualServer b/slsDetectorSoftware/gotthardDetectorServer/gotthardVirtualServer new file mode 100755 index 000000000..00f509290 Binary files /dev/null and b/slsDetectorSoftware/gotthardDetectorServer/gotthardVirtualServer differ diff --git a/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c new file mode 100755 index 000000000..4670e4968 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/mcb_funcs.c @@ -0,0 +1,2499 @@ +#ifdef MCB_FUNCS + +#include +#include +#include +#include +#include +#include "registers_g.h" + +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" + +/* global variables */ +#undef DEBUG +#undef DEBUGOUT + +extern int nModX; +//extern int dataBytes; +extern int dynamicRange; +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +enum detectorSettings thisSettings; + +int sChan, sChip, sMod, sDac, sAdc; +const int allSelected=-2; +const int noneSelected=-1; + + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +int *detectorDacs=NULL; +int *detectorAdcs=NULL; +//int numberOfProbes; + +ROI rois[MAX_ROIS]; +int nROI=0; + + +int initDetector() { + + int imod; + // sls_detector_module *myModule; + int n=getNModBoard(); + nModX=n; + +#ifdef VERBOSE + printf("Board is for %d modules\n",n); +#endif + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorChips=malloc(n*NCHIP*sizeof(int)); + detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); + detectorDacs=malloc(n*NDAC*sizeof(int)); + detectorAdcs=malloc(n*NADC*sizeof(int)); +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",(unsigned int)(detectorModules), (unsigned int)(detectorModules+n)); + printf("chips from 0x%x to 0x%x\n",(unsigned int)(detectorChips), (unsigned int)(detectorChips+n*NCHIP)); + printf("chans from 0x%x to 0x%x\n",(unsigned int)(detectorChans), (unsigned int)(detectorChans+n*NCHIP*NCHAN)); + printf("dacs from 0x%x to 0x%x\n",(unsigned int)(detectorDacs), (unsigned int)(detectorDacs+n*NDAC)); + printf("adcs from 0x%x to 0x%x\n",(unsigned int)(detectorAdcs), (unsigned int)(detectorAdcs+n*NADC)); +#endif + for (imod=0; imoddacs=detectorDacs+imod*NDAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*NADC; + (detectorModules+imod)->chipregs=detectorChips+imod*NCHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*NCHIP*NCHAN; + (detectorModules+imod)->ndac=NDAC; + (detectorModules+imod)->nadc=NADC; + (detectorModules+imod)->nchip=NCHIP; + (detectorModules+imod)->nchan=NCHIP*NCHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + + /* + setCSregister(ALLMOD); //commented out by dhanya + setSSregister(ALLMOD); + counterClear(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + */ + + /* initialize dynamic range etc. */ + /* dynamicRange=getDynamicRange(); //always 16 not required commented out + nModX=setNMod(-1);*/ + + //dataBytes=nModX*NCHIP*NCHAN*4; + // dynamicRange=32; + // initChip(0, 0,ALLMOD); + //nModX=n; + // + allocateRAM(); + + + return OK; +} + + + + +int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) { + destChan->chan=srcChan->chan; + destChan->chip=srcChan->chip; + destChan->module=srcChan->module; + destChan->reg=srcChan->reg; + return OK; +} + + +int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip) { + + int ichan; + int ret=OK; + if ((srcChip->nchan)>(destChip->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + + destChip->nchan=srcChip->nchan; + destChip->reg=srcChip->reg; + destChip->chip=srcChip->chip; + destChip->module=srcChip->module; + for (ichan=0; ichan<(srcChip->nchan); ichan++) { + *((destChip->chanregs)+ichan)=*((srcChip->chanregs)+ichan); + } + return ret; +} + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { + + int ichip, idac, ichan, iadc; + + int ret=OK; + +#ifdef VERBOSE + printf("Copying module %x to module %x\n",(unsigned int)(srcMod),(unsigned int)(destMod)); +#endif + + if (srcMod->module>=0) { +#ifdef VERBOSE + printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); +#endif + destMod->module=srcMod->module; + } + if (srcMod->serialnumber>=0){ +/* #ifdef VERBOSE */ +/* printf("Copying module serial number %x to module serial number %x\n",srcMod->serialnumber,destMod->serialnumber); */ +/* #endif */ + destMod->serialnumber=srcMod->serialnumber; + } + if ((srcMod->nchip)>(destMod->nchip)) { + printf("Number of chip of source is larger than number of chips of destination\n"); + return FAIL; + } + if ((srcMod->nchan)>(destMod->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + if ((srcMod->ndac)>(destMod->ndac)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + if ((srcMod->nadc)>(destMod->nadc)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + +#ifdef VERBOSE + printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); + printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); + printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); + printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); + +#endif + + + + destMod->ndac=srcMod->ndac; + destMod->nadc=srcMod->nadc; + destMod->nchip=srcMod->nchip; + destMod->nchan=srcMod->nchan; + if (srcMod->reg>=0) + destMod->reg=srcMod->reg; +#ifdef VERBOSE + printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); +#endif + if (srcMod->gain>=0) + destMod->gain=srcMod->gain; + if (srcMod->offset>=0) + destMod->offset=srcMod->offset; + + // printf("copying gain and offset %f %f to %f %f\n",srcMod->gain,srcMod->offset,destMod->gain,destMod->offset); + + for (ichip=0; ichip<(srcMod->nchip); ichip++) { + if (*((srcMod->chipregs)+ichip)>=0) + *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); + } + for (ichan=0; ichan<(srcMod->nchan); ichan++) { + if (*((srcMod->chanregs)+ichan)>=0) + *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); + } + for (idac=0; idac<(srcMod->ndac); idac++) { + if (*((srcMod->dacs)+idac)>=0) + *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } + for (iadc=0; iadc<(srcMod->nadc); iadc++) { + if (*((srcMod->adcs)+iadc)>=0) + *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); + } + return ret; +} + + + +/* Register commands */ + + +int clearDACSregister(int imod) { + + putout("1111111111111111",imod);//reset + putout("1111111111111110",imod);//cs down + + /* commented out by dhanya + putout("0000000001000000",imod); + putout("0000000101000000",imod); + putout("0000000101000000",imod); + putout("0000000001000000",imod); + */ +#ifdef DEBUG + fprintf(stdout, "Clearing DAC shiftregister\n"); +#endif + // sDac=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + +int nextDAC(int imod) { + + putout("1111111111111011",imod);//cs up + putout("1111111111111001",imod);//clk down + putout("1111111111111111",imod);//reset + + /*commented out by dhanya + putout("0000000001000000",imod); + putout("0000000001001000",imod); + putout("0000000001000000",imod); + */ +#ifdef DEBUG + fprintf(stdout, "Next DAC\n"); +#endif + // sDac++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + + +int clearCSregister(int imod) { + + putout("0000000001000000",imod); + putout("0000100001000000",imod); + putout("0000100001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Clearing CS shiftregister\n"); +#endif + /* + sChan=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + */ + sChip=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + //putout("0000000000000000",imod); + return 0; +} + +int setCSregister(int imod){ + + putout("0000000001000000",imod); + putout("0001000001000000",imod); + putout("0001000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Setting CS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChip=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextChip(int imod){ + + putout("0000000001000000",imod); + putout("0010000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Next Chip\n"); +#endif + sChip++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int firstChip(int imod){ + + putout("0100000001000000",imod); + putout("0110000001000000",imod); + putout("0100000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "First Chip\n"); +#endif + sChip=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int clearSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0000111000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Clearing SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int setSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0001011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Setting SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextStrip(int imod){ + putout("0000011000000000",imod); + putout("0010011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"|-"); +#endif + sChan++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int selChannel(const int strip,int imod) { + int istrip; + clearSSregister(imod); + nextStrip(imod); + for (istrip=0; istrip=0 && imod=0) + initDAC(ind,val, imod); + + if (imod>=0 && imodndac) + return (detectorDacs[ind+imod*NDAC]); + } + return FAIL; + */ + return setDACRegister(ind, -1, imod); +} + + +int initDAC(int dac_addr, int value, int imod) { +// int i; +#ifdef VERBOSE + printf("Programming dac %d with value %d\n", dac_addr, value); +#endif + clearDACSregister(imod); + program_one_dac(dac_addr,value,imod); + nextDAC(imod); + clearDACSregister(imod); + + return 0; +} + +int getTemperatureByModule(int tempSensor, int imod) +{ + int im; + //for the particular module + if (imod>=0 && imod=0 && imod=0 && imod=0) { +#ifdef VERBOSE + fprintf(stdout, "voltage %d\n", *(v+iaddr)); +#endif + program_one_dac(iaddr, *(v+iaddr),imod); + } + nextDAC(imod); + } + + + clearDACSregister(imod); + + return 0; + +} + + + + +int setSettings(int i, int imod) { +#ifdef VERBOSE + if(i==-1) + printf("\nReading settings of detector...\n"); + else + printf("\ninside set settings wit settings=%d...\n",i); +#endif + int confgain[] = CONF_GAIN; + int isett=-2,retval; + + //reading settings + if(i==GET_SETTINGS){ + retval=initConfGainByModule(i,i,imod); + if(retval==i) + isett=UNDEFINED; + } + //writing settings + else{ + retval=initConfGainByModule(i,confgain[i],imod); + if(retval!=i) + isett=UNDEFINED; + } + //if error while read/writing + if(isett==UNDEFINED) + printf("Error:Weird Value read back from the Gain/Settings Reg\n"); + else{ + //validating the settings read back + if((retval>=HIGHGAIN)&&(retval<=VERYHIGHGAIN)) + isett=retval; + else{ + isett=UNDEFINED; + printf("Error:Wrong Settings Read out:%d\n",retval); + } + } + thisSettings=isett; +//#ifdef VERBOSE + printf("detector settings are %d\n",thisSettings); +//#endif + return thisSettings; +} + + + + +/* Initialization*/ + +int initChannelbyNumber(sls_detector_channel myChan) { + int reg=myChan.reg; + int ft=reg & TRIM_DR; + int cae=(reg>>(NTRIMBITS))&1; + int ae=(reg>>(NTRIMBITS+1))&1; + int coe=(reg>>(NTRIMBITS+2))&1; + int ocoe=(reg>>(NTRIMBITS+3))&1; + int counts=(reg>>(NTRIMBITS+4)); +#ifdef VERBOSE + printf("Initializing channel %d chip %d module %d reg %x\n",myChan.chan,myChan.chip,myChan.module, reg); + printf("trim %d, cae %d, ae %d, coe %d, ocoe %d, counts %d\n",ft, cae, ae, coe, ocoe, counts); +#endif + + if (myChan.chip<0) + setCSregister(myChan.module); + else + selChip(myChan.chip,myChan.module); + + if (myChan.chan<0) + setSSregister(myChan.module); + else + selChannel(myChan.chan,myChan.module); + + initChannel(ft,cae,ae, coe, ocoe, counts,myChan.module); + + setDynamicRange(dynamicRange); + + setCSregister(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + + return myChan.reg; + +} + +int getChannelbyNumber(sls_detector_channel* myChan) { + int imod, ichip, ichan; + imod=myChan->module; + ichip=myChan->chip; + ichan=myChan->chan; + + if (detectorChans) { + if (imod=0) { + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + myChan->reg=detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan]; + return OK; + } + } + return FAIL; + +} + +int getTrimbit(int imod, int ichip, int ichan) { + if (detectorChans) { + if (imod=0) + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + return (detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan] & TRIM_DR); + } + + return -1; +} + +int initChannel(int ft,int cae, int ae, int coe, int ocoe, int counts, int imod){ + + int ibit, bit, i, im, ichip, ichan; + int chanmi, chanma, chipmi, chipma, modmi, modma; + + + + sMod=imod; + // printf("initializing module %d\n",sMod); + if (imod==ALLMOD) { + sMod=allSelected; + + // printf("initializing all modules\n"); + } + + if (sChan==allSelected) { + // printf("initializing all channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=NCHAN; + } else if (sChan==noneSelected || sChan>NCHAN || sChan<0) { + // printf("initializing no channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=-1; + } else { + // printf("initializing channel %d ft=%d coe=%d\n",sChan, ft,coe); + chanmi=sChan; + chanma=sChan+1; + } + + if (sChip==allSelected) { + // printf("initializing all chips\n"); + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + // printf("initializing no chips\n"); + chipmi=0; + chipma=-1; + } else { + // printf("initializing chip %d\n",sChip); + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + return 1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChans) { + for (im=modmi; im63 || ft<0) { + fprintf(stdout,"Fine Threshold is %d while should be between 0 and 63!",ft); + return 1; + } + /*cal_enable*/ + if (cae) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + } + /*n_an_enable*/ + if (ae) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } else { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } + /*trb5*/ + ibit=5; + bit=ft & (1<>1; + int nchan, ichan; + int ft, cae, ae, coe, ocoe, counts, chanreg; + + + + nchan=myChip.nchan; + if (ichip<0) + setCSregister(imod); + else + selChip(ichip,imod); + + clearSSregister(imod); + for (ichan=0; ichan>(NTRIMBITS+1))&1; + ae=(chanreg>>(NTRIMBITS+2))&1; + coe=((chanreg)>>(NTRIMBITS+3))&1; + ocoe=((chanreg)>>(NTRIMBITS+4))&1; + counts=((chanreg)>>(NTRIMBITS+5)); + nextStrip(imod); + initChannel(ft,cae,ae, coe, ocoe, counts,imod); + } + initChip(obe,ow,imod); + return myChip.reg; + +} + +int getChipbyNumber(sls_detector_chip* myChip){ + int imod, ichip; + imod=myChip->module; + ichip=myChip->chip; + + if (detectorChips) { + if (imodnchip) { + myChip->reg=detectorChips[ichip+imod*NCHIP]; + myChip->nchan=NCHAN; + myChip->chanregs=detectorChans+imod*NCHAN*NCHIP+ichip*NCHIP; + return OK; + } + } + return FAIL; + +} + + + +int initChip(int obe, int ow,int imod){ + int i; + int im, ichip; + int chipmi, chipma, modmi, modma; + /* switch (ow) { + case 0:; + case 1: + setDynamicRange(32); + break; + case 2: + setDynamicRange(16); + break; + case 3: + setDynamicRange(8); + break; + case 4: + setDynamicRange(4); + break; + case 5: + setDynamicRange(1); + break; + default: + setDynamicRange(32); + break; + } + */ + +#ifdef DEBUGOUT + printf("Initializing chip\n"); +#endif + putout("0000000000000000",imod); +#ifdef DEBUGOUT + printf("Output mode= %d\n", ow); +#endif + + /* clearing shift in register */ + for (i=0; i<10; i++) + putout("0000100000000000",imod); + putout("0000000000000000",imod); + + if (ow>0) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + for (i=0; i<(OUTMUX_OFFSET-1); i++) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>1) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>2) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>3) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>4) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + } +#ifdef DEBUGOUT + printf("Output buffer enable= %d\n", obe); +#endif + if (obe) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + /*}*/ + putout("0000000000000000",imod); + + + + + + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + + + if (sChip==allSelected) { + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imNCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imnModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorModules) { + for (im=modmi; imreg)=cm; +#ifdef VERBOSE + printf("imod=%d reg=%d (%x)\n",im,(detectorModules+im)->reg,(unsigned int)((detectorModules+im))); +#endif + } + } + return 0; +} + +int initModulebyNumber(sls_detector_module myMod) { + + printf("\ninside initmoduleynumber..\n"); + + int nchip,nchan;//int ichip, nchip, ichan, nchan; + int im, modmi,modma; + // int ft, cae, ae, coe, ocoe, counts, chanreg; + int imod; + // int obe; + // int ow; + int v[NDAC]; + + + nchip=myMod.nchip; + nchan=(myMod.nchan)/nchip; + + imod=myMod.module; + sMod=imod; + + if (sMod==ALLMOD) + sMod=allSelected; + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {// (sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + + /* + for (idac=0; idacmodule; +#ifdef VERBOSE + printf("Getting module %d\n",imod); +#endif + if (detectorModules) { + copyModule(myMod,detectorModules+imod); + ; + } else + return FAIL; + + return OK; +} + +/* To chips */ +int clearCounter(int imod){ + int i; +#ifdef DEBUG + printf("Clearing counter with contclear\n"); +#endif + putout("0000000000000000",imod); + for (i=0; i<10; i++) + putout("0000000000010000",imod); + putout("0000000000000000",imod); + + return 0; +} + +int clearOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Clearing output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0000110000000000",imod); + putout("0000010000000000",imod); + return 0; +} +int setOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Setting output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0001010000000000",imod); + putout("0000010000000000",imod); + return 0; +} + + +int extPulse(int ncal, int imod) { + int ical; +#ifdef DEBUG + printf("Giving a clock pulse to the counter\n"); +#endif + for (ical=0; ical0 && i%2==0) { + printf("Shift in: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<0 && (dum & (1<0) { + printf("Shift out: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, (dum &1<0 && i%2==0) { + printf("Shift stsel: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<> 1; + + + putout("0000000000000000",ALLMOD); + putout("0010000000000000",ALLMOD); //change mux setting + putout("0000000000000000",ALLMOD); + } + + printf("Test FpgaMux module %d : %d errors\n", imod,result); + if (result) + return 1; + else + return 0; +} + + + + + + + + + +int calibration_sensor(int num, int *v, int *dacs) { + int ich, ichip, imod; + int val[10]; + + + printf("calibrating sensor..."); + for (imod=0; imod=0){ + + //clear rois + for(i=0;i=0) && (adc<=4)); + else { + printf("warning:adc value greater than 5. deleting roi\n"); + adc=-1; + } + } + } + + + //set rois for just 1 adc - take only 1st roi + if(adc!=-1){ + rois[0].xmin=adc*(NCHAN*NCHIPS_PER_ADC); + rois[0].xmax=(adc+1)*(NCHAN*NCHIPS_PER_ADC)-1; + rois[0].ymin=-1; + rois[0].ymax=-1; + nROI = 1; + }else + nROI = 0; + + if((arg[0].xmin!=rois[0].xmin)||(arg[0].xmax!=rois[0].xmax)||(arg[0].ymin!=rois[0].ymin)||(arg[0].ymax!=rois[0].ymax)) + *ret=FAIL; + if(n!=nROI) + *ret=FAIL; + + //set adc of interest + setADC(adc); + } + +//#ifdef VERBOSE + printf("Rois:\n"); + for( i=0;i + + +extern int sockfd; +extern int phase_shift; + + + +void error(char *msg) +{ + perror(msg); +} + +int main(int argc, char *argv[]) +{ + int portno, b; + char cmd[100]; + int retval=OK; + int sd, fd; + int iarg; + for(iarg=1; iarg + + +// Hardware definitions + +#define NCHAN 128 +#define NCHIP 10 +#define NMAXMODX 1 +#define NMAXMODY 1 +#define NMAXMOD NMAXMODX*NMAXMODY +#define NDAC 8 +#define NADC 5 + +#define NCHANS NCHAN*NCHIP*NMAXMOD +#define NDACS NDAC*NMAXMOD + +#define NTRIMBITS 6 +#define NCOUNTBITS 24 + +#define NCHIPS_PER_ADC 2 + +//#define TRIM_DR ((2**NTRIMBITS)-1) +//#define COUNT_DR ((2**NCOUNTBITS)-1) +#define TRIM_DR (((int)pow(2,NTRIMBITS))-1) +#define COUNT_DR (((int)pow(2,NCOUNTBITS))-1) + + +#define ALLMOD 0xffff +#define ALLFIFO 0xffff + + +#define ADCSYNC_VAL 0x32214 +#define TOKEN_RESTART_DELAY 0x88000000 +#define TOKEN_RESTART_DELAY_ROI 0x1b000000 +#define TOKEN_TIMING_REV1 0x1f16 +#define TOKEN_TIMING_REV2 0x1f0f + +#define DEFAULT_PHASE_SHIFT 120 +#define DEFAULT_IP_PACKETSIZE 0x0522 +#define DEFAULT_UDP_PACKETSIZE 0x050E +#define ADC1_IP_PACKETSIZE 256*2+14+20 +#define ADC1_UDP_PACKETSIZE 256*2+4+8+2 + +#ifdef VIRTUAL +#define DEBUGOUT +#endif + +#define CLK_FREQ 32.1E+6 + + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c new file mode 100755 index 000000000..775cb9de1 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.c @@ -0,0 +1,3058 @@ +#include "sls_detector_defs.h" +#include "server_funcs.h" +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "trimming_funcs.h" +#include "registers_g.h" +#include "gitInfoGotthard.h" + +#define FIFO_DATA_REG_OFF 0x50<<11 +#define CONTROL_REG 0x24<<11 +// Global variables + +int (*flist[256])(int); + +//defined in the detector specific file +#ifdef MYTHEND +const enum detectorType myDetectorType=MYTHEN; +#elif PROPIXD +const enum detectorType myDetectorType=PROPIX; +#elif GOTTHARDD +const enum detectorType myDetectorType=GOTTHARD; +#elif EIGERD +const enum detectorType myDetectorType=EIGER; +#elif PICASSOD +const enum detectorType myDetectorType=PICASSO; +#elif MOENCHD +const enum detectorType myDetectorType=MOENCH; +#else +const enum detectorType myDetectorType=GENERIC; +#endif + + +extern int nModX; +extern int nModY; +extern int dataBytes; +extern int dynamicRange; +extern int storeInRAM; + +extern int lockStatus; +extern char lastClientIP[INET_ADDRSTRLEN]; +extern char thisClientIP[INET_ADDRSTRLEN]; +extern int differentClients; + +/* global variables for optimized readout */ +extern unsigned int *ram_values; +char *dataretval=NULL; +int nframes, iframes, dataret; +char mess[MAX_STR_LENGTH]; + +int digitalTestBit = 0; + + +int init_detector( int b) { + + if (mapCSP0()==FAIL) { + printf("Could not map memory\n"); + exit(-1); + } + + //confirm if it is really gotthard + if (((bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>> DETECTOR_TYPE_OFFSET) == MOENCH_MODULE){ + printf("This is a MOENCH detector. Exiting Gotthard Server.\n\n"); + exit(-1); + } + + if (b) { +#ifdef PROPIXD + printf("***This is a PROPIX detector***\n"); +#else + printf("***This is a GOTTHARD detector with %d chips per module***\n", NCHIP); +#endif + printf("\nBoard Revision:0x%x\n",(bus_r(PCB_REV_REG)&BOARD_REVISION_MASK)); +#ifdef MCB_FUNCS + initDetector(); + printf("Initializing Detector\n"); +#endif + testFpga(); + testRAM(); + + //gotthard specific + setPhaseShiftOnce(); + prepareADC(); + setADC(-1); //already does setdaqreg and clean fifo + setSettings(GET_SETTINGS,-1); + + //Initialization + setFrames(1); + setTrains(1); + setExposureTime(1e6); + setPeriod(1e9); + setDelay(0); + setGates(0); + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + setMaster(GET_MASTER); + setSynchronization(GET_SYNCHRONIZATION_MODE); + startReceiver(0); + } + strcpy(mess,"dummy message"); + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + lockStatus=0; + return OK; +} + + +int decode_function(int file_des) { + int fnum,n; + int retval=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveDataOnly(file_des,&fnum,sizeof(fnum)); + if (n <= 0) { +#ifdef VERBOSE + printf("ERROR reading from socket %d, %d %d\n", n, fnum, file_des); +#endif + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif + +#ifdef VERBOSE + printf( "calling function fnum = %d %x\n",fnum,(unsigned int)(flist[fnum])); +#endif + if (fnum<0 || fnum>255) + fnum=255; + retval=(*flist[fnum])(file_des); + if (retval==FAIL) + printf( "Error executing the function = %d \n",fnum); + return retval; +} + + +int function_table() { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_EXEC_COMMAND]=&exec_command; + flist[F_GET_DETECTOR_TYPE]=&get_detector_type; + flist[F_SET_NUMBER_OF_MODULES]=&set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES]=&get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG]=&set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE]=&set_external_communication_mode; + flist[F_GET_ID]=&get_id; + flist[F_DIGITAL_TEST]=&digital_test; + flist[F_WRITE_REGISTER]=&write_register; + flist[F_READ_REGISTER]=&read_register; + flist[F_SET_DAC]=&set_dac; + flist[F_GET_ADC]=&get_adc; + flist[F_SET_CHANNEL]=&set_channel; + flist[F_SET_CHIP]=&set_chip; + flist[F_SET_MODULE]=&set_module; + flist[F_GET_CHANNEL]=&get_channel; + flist[F_GET_CHIP]=&get_chip; + flist[F_GET_MODULE]=&get_module; + flist[F_GET_THRESHOLD_ENERGY]=&get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY]=&set_threshold_energy; + flist[F_SET_SETTINGS]=&set_settings; + flist[F_START_ACQUISITION]=&start_acquisition; + flist[F_STOP_ACQUISITION]=&stop_acquisition; + flist[F_START_READOUT]=&start_readout; + flist[F_GET_RUN_STATUS]=&get_run_status; + flist[F_READ_FRAME]=&read_frame; + flist[F_READ_ALL]=&read_all; + flist[F_START_AND_READ_ALL]=&start_and_read_all; + flist[F_SET_TIMER]=&set_timer; + flist[F_GET_TIME_LEFT]=&get_time_left; + flist[F_SET_DYNAMIC_RANGE]=&set_dynamic_range; + flist[F_SET_ROI]=&set_roi; + flist[F_SET_SPEED]=&set_speed; + flist[F_SET_READOUT_FLAGS]=&set_readout_flags; + flist[F_EXECUTE_TRIMMING]=&execute_trimming; + flist[F_LOCK_SERVER]=&lock_server; + flist[F_SET_PORT]=&set_port; + flist[F_GET_LAST_CLIENT_IP]=&get_last_client_ip; + flist[F_UPDATE_CLIENT]=&update_client; + flist[F_CONFIGURE_MAC]=&configure_mac; + flist[F_LOAD_IMAGE]=&load_image; + flist[F_SET_MASTER]=&set_master; + flist[F_SET_SYNCHRONIZATION_MODE]=&set_synchronization; + flist[F_READ_COUNTER_BLOCK]=&read_counter_block; + flist[F_RESET_COUNTER_BLOCK]=&reset_counter_block; + flist[F_START_RECEIVER]=&start_receiver; + flist[F_STOP_RECEIVER]=&stop_receiver; + flist[F_CALIBRATE_PEDESTAL]=&calibrate_pedestal; + return OK; +} + + +int M_nofunc(int file_des){ + + int ret=FAIL; + sprintf(mess,"Unrecognized Function\n"); + printf(mess); + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + + +int exit_server(int file_des) { + int retval=FAIL; + sendDataOnly(file_des,&retval,sizeof(retval)); + printf("closing server."); + sprintf(mess,"closing server"); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + +int exec_command(int file_des) { + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int retval=OK; + int sysret=0; + int n=0; + + /* receive arguments */ + n = receiveDataOnly(file_des,cmd,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + if (lockStatus==0 || differentClients==0) + sysret=system(cmd); + + //should be replaced by popen + if (sysret==0) { + sprintf(answer,"Succeeded\n"); + if (lockStatus==1 && differentClients==1) + sprintf(answer,"Detector locked by %s\n", lastClientIP); + } else { + sprintf(answer,"Failed\n"); + retval=FAIL; + } + } else { + sprintf(answer,"Could not receive the command\n"); + } + + /* send answer */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + n = sendDataOnly(file_des,answer,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + + /*return ok/fail*/ + return retval; + +} + + + +int get_detector_type(int file_des) { + int n=0; + enum detectorType ret; + int retval=OK; + + sprintf(mess,"Can't return detector type\n"); + + + /* receive arguments */ + /* execute action */ + ret=myDetectorType; + +#ifdef VERBOSE + printf("Returning detector type %d\n",ret); +#endif + + /* send answer */ + /* send OK/failed */ + if (differentClients==1) + retval=FORCE_UPDATE; + + n += sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + + +} + + +int set_number_of_modules(int file_des) { + int n; + int arg[2], ret=0; + int retval=OK; + int dim, nm; + + sprintf(mess,"Can't set number of modules\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket %d", n); + retval=GOODBYE; + } + if (retval==OK) { + dim=arg[0]; + nm=arg[1]; + + /* execute action */ +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + + //if (nm!=GET_FLAG) { + if (dim!=X && nm!=GET_FLAG) { + retval=FAIL; + sprintf(mess,"Can't change module number in dimension %d\n",dim); + } else { + if (lockStatus==1 && differentClients==1 && nm!=GET_FLAG) { + sprintf(mess,"Detector locked by %s\n", lastClientIP); + retval=FAIL; + } else { + ret=setNMod(nm); + if (nModX==nm || nm==GET_FLAG) { + retval=OK; + if (differentClients==1) + retval=FORCE_UPDATE; + } else + retval=FAIL; + } + } + } + /*} else { + if (dim==Y) { + ret=nModY; + } else if (dim==X) { + ret=setNMod(-1); + } + } + */ + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + +} + + +int get_max_number_of_modules(int file_des) { + int n; + int ret; + int retval=OK; + enum dimension arg; + + sprintf(mess,"Can't get max number of modules\n"); + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* execute action */ +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif + + + switch (arg) { + case X: + ret=getNModBoard(); + break; + case Y: + ret=NMAXMODY; + break; + default: + ret=FAIL; + retval=FAIL; + break; + } +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,ret ); +#endif + + + + if (differentClients==1 && retval==OK) { + retval=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + + /*return ok/fail*/ + return retval; +} + + +//index 0 is in gate +//index 1 is in trigger +//index 2 is out gate +//index 3 is out trigger + +int set_external_signal_flag(int file_des) { + int n; + int arg[2]; + int ret=OK; + int signalindex; + enum externalSignalFlag flag, retval; + + sprintf(mess,"Can't set external signal flag\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + retval=SIGNAL_OFF; + if (ret==OK) { + signalindex=arg[0]; + flag=arg[1]; + /* execute action */ + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + + default: + if (differentClients==0 || lockStatus==0) { + retval=setExtSignal(signalindex,flag); + } else { + if (lockStatus!=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n", lastClientIP); + } + } + + } + +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag ); + printf("Set to flag %d\n",retval); +#endif + + } else { + ret=FAIL; + } + + if (ret==OK && differentClients!=0) + ret=FORCE_UPDATE; + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + +int set_external_communication_mode(int file_des) { + int n; + enum externalCommunicationMode arg, ret=GET_EXTERNAL_COMMUNICATION_MODE; + int retval=OK; + + sprintf(mess,"Can't set external communication mode\n"); + + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* + enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE + }; + */ + if (retval==OK) { + /* execute action */ + + ret=setTiming(arg); + + /* switch(arg) { */ + /* default: */ + /* sprintf(mess,"The meaning of single signals should be set\n"); */ + /* retval=FAIL; */ + /* } */ + + +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif + } else + ret=FAIL; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return retval; +} + + + +int get_id(int file_des) { + // sends back 64 bits! + int64_t retval=-1; + int ret=OK; + int n=0; + enum idMode arg; + + sprintf(mess,"Can't return id\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + + switch (arg) { + case DETECTOR_SERIAL_NUMBER: + retval=getDetectorNumber(); + break; + case DETECTOR_FIRMWARE_VERSION: + retval=getFirmwareSVNVersion(); + retval=(retval <<32) | getFirmwareVersion(); + break; + case DETECTOR_SOFTWARE_VERSION: + retval= SVNREV; + retval= (retval <<32) | SVNDATE; + break; +/* case DETECTOR_FIRMWARE_SVN_VERSION: + retval=getFirmwareSVNVersion(); + break;*/ + default: + printf("Required unknown id %d \n", arg); + ret=FAIL; + retval=FAIL; + break; + } + +#ifdef VERBOSE + printf("Id is %llx\n", retval); +#endif + + if (differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int digital_test(int file_des) { + + int retval; + int ret=OK; + int imod=-1; + int n=0; + int ibit=0; + int ow; + int ival; + enum digitalTestMode arg; + + sprintf(mess,"Can't send digital test\n"); + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Digital test mode %d\n",arg ); +#endif + + switch (arg) { + case CHIP_TEST: + n = receiveDataOnly(file_des,&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + retval=0; +#ifdef MCB_FUNCS + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + break; + } + if (imod >= nModX) { + ret=FAIL; + sprintf(mess,"Module %d disabled\n",imod); + break; + } + if (testShiftIn(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftOut(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftStSel(imod)) retval|=(1<<(ibit)); + ibit++; + //if ( testDataInOut(0x123456, imod)) retval|=(1<<(ibit++)); + //if ( testExtPulse(imod)) retval|=(1<<(ibit++)); + // for (ow=0; ow<6; ow++) + // ow=1; + //#ifndef PICASSOD + for (ow=0; ow<5; ow++) { + //#endif + if (testDataInOutMux(imod, ow, 0x789abc)) retval|=(1<=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + +#ifdef MCB_FUNCS + switch (ind) { + case G_VREF_DS : + idac=VREF_DS; + break; + case G_VCASCN_PB: + idac=VCASCN_PB; + break; + case G_VCASCP_PB: + idac=VCASCP_PB; + break; + case G_VOUT_CM: + idac=VOUT_CM; + break; + case G_VCASC_OUT: + idac=VCASC_OUT; + break; + case G_VIN_CM: + idac=VIN_CM; + break; + case G_VREF_COMP: + idac=VREF_COMP; + break; + case G_IB_TESTC: + idac=IB_TESTC; + break; + case HV_POT: + idac=HIGH_VOLTAGE; + break; + + default: + printf("Unknown DAC index %d\n",ind); + sprintf(mess,"Unknown DAC index %d\n",ind); + ret=FAIL; + break; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + if(idac==HIGH_VOLTAGE){ + retval[0]=initHighVoltageByModule(val,imod); + ret=FAIL; + if(retval[0]==-2) + strcpy(mess,"Invalid Voltage.Valid values are 0,90,110,120,150,180,200"); + else if(retval[0]==-3) + strcpy(mess,"Weird value read back or it has not been set yet\n"); + else + ret=OK; + }else{ + initDACbyIndexDACU(idac,val,imod,mV,retval); + ret=FAIL; + if(mV) + temp = retval[1]; + else + temp = retval[0]; + if ((abs(temp-val)<=3) || val==-1) { + ret=OK; +#ifdef VERBOSE + printf("DAC set to %d in dac units and %d mV\n", retval[0],retval[1]); +#endif + } + } + } + } + +#endif + + + if(ret==FAIL) + printf("Setting dac %d of module %d: wrote %d but read %d\n", ind, imod, val, temp); + else{ + if (differentClients) + ret=FORCE_UPDATE; + } + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + +int get_adc(int file_des) { + //default: mod 0 + int retval; + int ret=OK; + int arg[2]; + enum dacIndex ind; + int imod; + int n; + int idac=0; + + sprintf(mess,"Can't read ADC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ind=arg[0]; + imod=arg[1]; + +#ifdef VERBOSE + printf("Getting ADC %d of module %d\n", ind, imod); +#endif + + if (imod>=getNModBoard() || imod<0) + ret=FAIL; + +#ifdef MCB_FUNCS + switch (ind) { + case TEMPERATURE_FPGA: + idac=TEMP_FPGA; + break; + case TEMPERATURE_ADC: + idac=TEMP_ADC; + break; + default: + printf("Unknown DAC index %d\n",ind); + sprintf(mess,"Unknown DAC index %d\n",ind); + ret=FAIL; + break; + } + + if (ret==OK) + retval=getTemperatureByModule(idac,imod); +#endif + +#ifdef VERBOSE + printf("ADC is %d V\n", retval); +#endif + if (ret==FAIL) { + printf("Getting adc %d of module %d failed\n", ind, imod); + } + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int set_channel(int file_des) { + int ret=OK; + sls_detector_channel myChan; + int retval; + int n; + + + sprintf(mess,"Can't set channel\n"); + +#ifdef VERBOSE + printf("Setting channel\n"); +#endif + ret=receiveChannel(file_des, &myChan); + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif + + if (ret==OK) { + if (myChan.module>=getNModBoard()) + ret=FAIL; + if (myChan.chip>=NCHIP) + ret=FAIL; + if (myChan.chan>=NCHAN) + ret=FAIL; + if (myChan.module<0) + myChan.module=ALLMOD; + } + + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChannelbyNumber(myChan); +#endif + } + } + /* Maybe this is done inside the initialization funcs */ + //copyChannel(detectorChans[myChan.module][myChan.chip]+(myChan.chan), &myChan); + + + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + + +int get_channel(int file_des) { + + int ret=OK; + sls_detector_channel retval; + + int arg[3]; + int ichan, ichip, imod; + int n; + + sprintf(mess,"Can't get channel\n"); + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichan=arg[0]; + ichip=arg[1]; + imod=arg[2]; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0 && ichan=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + + if (ret==OK) { + if (myChip.module>=getNModBoard()) + ret=FAIL; + if (myChip.module<0) + myChip.module=ALLMOD; + if (myChip.chip>=NCHIP) + ret=FAIL; + } + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChipbyNumber(myChip); +#endif + } + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + return ret; +} + +int get_chip(int file_des) { + + + int ret=OK; + sls_detector_chip retval; + int arg[2]; + int ichip, imod; + int n; + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichip=arg[0]; + imod=arg[1]; + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0) + ret=OK; + else + ret=FAIL; + + +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#endif + + if (ret==OK) { + if (myModule.module>=getNModBoard()) { + ret=FAIL; + printf("Module number is too large %d\n",myModule.module); + } + if (myModule.module<0) + myModule.module=ALLMOD; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initModulebyNumber(myModule); +#endif + } + } + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + free(myChip); + free(myChan); + free(myDac); + free(myAdc); + + // setDynamicRange(dr); always 16 commented out + + + return ret; +} + + + + +int get_module(int file_des) { + + + int ret=OK; + + + int arg; + int imod; + int n; + + + + sls_detector_module myModule; + int *myChip=malloc(NCHIP*sizeof(int)); + int *myChan=malloc(NCHIP*NCHAN*sizeof(int)); + int *myDac=malloc(NDAC*sizeof(int));/**dhanya*/ + int *myAdc=malloc(NADC*sizeof(int));/**dhanya*/ + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } + + myModule.ndac=NDAC; + myModule.nchip=NCHIP; + myModule.nchan=NCHAN*NCHIP; + myModule.nadc=NADC; + + + + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + imod=arg; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + } +#ifdef VERYVERBOSE + printf("%d %d %x %s\n",(int)(sizeof(mess)),(int)(strlen(mess)),(unsigned int)( mess),mess); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); +#ifdef VERYVERBOSE + printf("message sent %s\n",mess); +#endif + printf("dataret %d\n",dataret); + return dataret; + } + } else { + nframes=0; + while(fifo_read_event()) { + nframes++; + } + dataretval=(char*)ram_values; + dataret=OK; +#ifdef VERBOSE + printf("sending data of %d frames\n",nframes); +#endif + for (iframes=0; iframes-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + if (differentClients) + dataret=FORCE_UPDATE; + } +#ifdef VERBOSE + printf("Frames left %d\n",(int)(getFrames())); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + printf("dataret %d\n",dataret); + return dataret; + } + printf("dataret %d\n",dataret); + return dataret; +} + + + + + + + + +int read_all(int file_des) { + +while(read_frame(file_des)==OK) { + +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + return OK; + + +} + +int start_and_read_all(int file_des) { + //int dataret=OK; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + if (differentClients==1 && lockStatus==1) { + dataret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return dataret; + + } + + startStateMachine(); + + /* ret=startStateMachine(); + if (ret!=OK) { + sprintf(mess,"could not start state machine\n"); + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + #ifdef VERBOSE + printf("could not start state machine\n"); +#endif +} else {*/ + read_all(file_des); +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + //} + + + return OK; + + +} + +int set_timer(int file_des) { + enum timerIndex ind; + int64_t tns; + int n; + int64_t retval; + int ret=OK; + + + sprintf(mess,"can't set timer\n"); + + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&tns,sizeof(tns)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret!=OK) { + printf(mess); + } + +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif + if (ret==OK) { + + if (differentClients==1 && lockStatus==1 && tns!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch(ind) { + case FRAME_NUMBER: + retval=setFrames(tns); + break; + case ACQUISITION_TIME: + retval=setExposureTime(tns); + break; + case FRAME_PERIOD: + retval=setPeriod(tns); + break; + case DELAY_AFTER_TRIGGER: + retval=setDelay(tns); + break; + case GATES_NUMBER: + retval=setGates(tns); + break; + case PROBES_NUMBER: +#ifdef PROPIXD + sprintf(mess,"can't set/get number of probes for propix\n"); +#else + sprintf(mess,"can't set/get number of probes for gotthard\n"); +#endif + + ret=FAIL; + break; + case CYCLES_NUMBER: + retval=setTrains(tns); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + } + if (ret!=OK) { + printf(mess); + if (differentClients) + ret=FORCE_UPDATE; + } + + if (ret!=OK) { + printf(mess); + printf("set timer failed\n"); + } else if (ind==FRAME_NUMBER) { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess, "could not allocate RAM for %lld frames\n", tns); + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { +#ifdef VERBOSE + printf("returning ok %d\n",(int)(sizeof(retval))); +#endif + + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + + return ret; + +} + + + + + + + + +int get_time_left(int file_des) { + + enum timerIndex ind; + int n; + int64_t retval; + int ret=OK; + + sprintf(mess,"can't get timer\n"); + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + + printf("getting time left on timer %d \n",ind); +#endif + + if (ret==OK) { + switch(ind) { + case FRAME_NUMBER: + retval=getFrames(); + break; + case ACQUISITION_TIME: + retval=getExposureTime(); + break; + case FRAME_PERIOD: + retval=getPeriod(); + break; + case DELAY_AFTER_TRIGGER: + retval=getDelay(); + break; + case GATES_NUMBER: + retval=getGates(); + break; + case PROBES_NUMBER: + retval=getProbes(); + break; + case CYCLES_NUMBER: + retval=getTrains(); + break; + case PROGRESS: + retval=getProgress(); + break; + case ACTUAL_TIME: + retval=getActualTime(); + break; + case MEASUREMENT_TIME: + retval=getMeasurementTime(); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + + + if (ret!=OK) { + printf("get time left failed\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + +#ifdef VERBOSE + + printf("time left on timer %d is %lld\n",ind, retval); +#endif + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=OK) { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } +#ifdef VERBOSE + + printf("data sent\n"); +#endif + + return ret; + + +} + +int set_dynamic_range(int file_des) { + + + + int dr; + int n; + int retval; + int ret=OK; + + + sprintf(mess,"can't set dynamic range\n"); + + + n = receiveDataOnly(file_des,&dr,sizeof(dr)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + if (differentClients==1 && lockStatus==1 && dr>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setDynamicRange(dr); + } + + //if (dr>=0 && retval!=dr) ret=FAIL; + if (ret!=OK) { + sprintf(mess,"set dynamic range failed\n"); + } else { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess,"Could not allocate RAM for the dynamic range selected\n"); + else if (differentClients) + ret=FORCE_UPDATE; + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + +int set_roi(int file_des) { + + int i; + int ret=OK; + int nroi=-1; + int n=0; + int retvalsize=0; + ROI arg[MAX_ROIS]; + ROI* retval=0; + + strcpy(mess,"Could not set/get roi\n"); + + + n = receiveDataOnly(file_des,&nroi,sizeof(nroi)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef PROPIXD + sprintf(mess,"can't set roi for propix\n"); + ret = FAIL; +#endif + if(ret != FAIL){ + if(nroi!=-1){ + n = receiveDataOnly(file_des,arg,nroi*sizeof(ROI)); + if (n != (nroi*sizeof(ROI))) { + sprintf(mess,"Received wrong number of bytes for ROI\n"); + ret=FAIL; + } + //#ifdef VERBOSE + printf("Setting ROI to:"); + for( i=0;i=0) { + if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) + lockStatus=lock; + else { + ret=FAIL; + sprintf(mess,"Server already locked by %s\n", lastClientIP); + } + } + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else + n = sendDataOnly(file_des,&lockStatus,sizeof(lockStatus)); + + return ret; + +} + +int set_port(int file_des) { + int n; + int ret=OK; + int sd=-1; + + enum portType p_type; /** data? control? stop? Unused! */ + int p_number; /** new port number */ + + n = receiveDataOnly(file_des,&p_type,sizeof(p_type)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (ptype)\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&p_number,sizeof(p_number)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (pnum)\n"); + ret=FAIL; + } + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + printf("\n"); + ret=FAIL; + } + + printf("set port %d to %d\n",p_type, p_number); + + sd=bindSocket(p_number); + } + if (sd>=0) { + ret=OK; + if (differentClients ) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + printf("Could not bind port %d\n", p_number); + if (sd==-10) { + sprintf(mess,"Port %d already set\n", p_number); + printf("Port %d already set\n", p_number); + + } + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&p_number,sizeof(p_number)); + closeConnection(file_des); + exitServer(sockfd); + sockfd=sd; + + } + + return ret; + +} + +int get_last_client_ip(int file_des) { + int ret=OK; + int n; + if (differentClients ) + ret=FORCE_UPDATE; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + + return ret; + +} + + +int send_update(int file_des) { + + int ret=OK; + enum detectorSettings t; + int n;//int thr, n; + //int it; + int64_t retval, tns=-1; + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + n = sendDataOnly(file_des,&nModX,sizeof(nModX)); + n = sendDataOnly(file_des,&nModY,sizeof(nModY)); + n = sendDataOnly(file_des,&dynamicRange,sizeof(dynamicRange)); + n = sendDataOnly(file_des,&dataBytes,sizeof(dataBytes)); + t=setSettings(GET_SETTINGS,-1); + n = sendDataOnly(file_des,&t,sizeof(t)); +/* thr=getThresholdEnergy(); + n = sendDataOnly(file_des,&thr,sizeof(thr));*/ + retval=setFrames(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setExposureTime(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setPeriod(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setDelay(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setGates(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); +/* retval=setProbes(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t));*/ + retval=setTrains(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + + if (lockStatus==0) { + strcpy(lastClientIP,thisClientIP); + } + + return ret; + + +} +int update_client(int file_des) { + + int ret=OK; + + sendDataOnly(file_des,&ret,sizeof(ret)); + return send_update(file_des); + + + +} + + +int configure_mac(int file_des) { + + int ret=OK; + char arg[6][50]; + int n; + + int imod=0;//should be in future sent from client as -1, arg[2] + int ipad; + long long int imacadd; + long long int idetectormacadd; + int udpport; + int detipad; + int retval=-100; + + sprintf(mess,"Can't configure MAC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + sscanf(arg[0], "%x", &ipad); + sscanf(arg[1], "%llx", &imacadd); + sscanf(arg[2], "%x", &udpport); + sscanf(arg[3], "%llx", &idetectormacadd); + sscanf(arg[4], "%x", &detipad); + //arg[5] is udpport2 for eiger +#ifdef VERBOSE + int i; + printf("\ndigital_test_bit in server %d\t",digitalTestBit); + printf("\nipadd %x\t",ipad); + printf("destination ip is %d.%d.%d.%d = 0x%x \n",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff,ipad); + printf("macad:%llx\n",imacadd); + for (i=0;i<6;i++) + printf("mac adress %d is 0x%x \n",6-i,(unsigned int)(((imacadd>>(8*i))&0xFF))); + printf("udp port:0x%x\n",udpport); + printf("detector macad:%llx\n",idetectormacadd); + for (i=0;i<6;i++) + printf("detector mac adress %d is 0x%x \n",6-i,(unsigned int)(((idetectormacadd>>(8*i))&0xFF))); + printf("detipad %x\n",detipad); + printf("\n"); +#endif + + + + if (imod>=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + + //#ifdef VERBOSE + printf("Configuring MAC of module %d at port %x\n", imod, udpport); + //#endif +#ifdef MCB_FUNCS + if (ret==OK){ + if(runBusy()){ + ret=stopStateMachine(); + if(ret==FAIL) + strcpy(mess,"could not stop detector acquisition to configure mac"); + } + + if(ret==OK) + configureMAC(ipad,imacadd,idetectormacadd,detipad,digitalTestBit,udpport); + retval=getAdcConfigured(); + } +#endif + if (ret==FAIL) + printf("configuring MAC of mod %d failed\n", imod); + else + printf("Configuremac successful of mod %d and adc %d\n",imod,retval); + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + /*return ok/fail*/ + return ret; + +} + + + +int load_image(int file_des) { + int retval; + int ret=OK; + int n; + enum imageType index; + short int ImageVals[NCHAN*NCHIP]; + + sprintf(mess,"Loading image failed\n"); + + n = receiveDataOnly(file_des,&index,sizeof(index)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,ImageVals,dataBytes); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef PROPIXD + sprintf(mess,"can't load image for propix\n"); + ret = FAIL; +#endif + + switch (index) { + case DARK_IMAGE : +#ifdef VERBOSE + printf("Loading Dark image\n"); +#endif + break; + case GAIN_IMAGE : +#ifdef VERBOSE + printf("Loading Gain image\n"); +#endif + break; + default: + printf("Unknown index %d\n",index); + sprintf(mess,"Unknown index %d\n",index); + ret=FAIL; + break; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + retval=loadImage(index,ImageVals); + if (retval==-1) + ret = FAIL; + } + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + +int set_master(int file_des) { + + enum masterFlags retval=GET_MASTER; + enum masterFlags arg; + int n; + int ret=OK; + // int regret=OK; + + + sprintf(mess,"can't set master flags\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setMaster(arg); + + } + if (retval==GET_MASTER) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int set_synchronization(int file_des) { + + enum synchronizationMode retval=GET_MASTER; + enum synchronizationMode arg; + int n; + int ret=OK; + //int regret=OK; + + + sprintf(mess,"can't set synchronization mode\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + //ret=setStoreInRAM(0); + // initChipWithProbes(0,0,0, ALLMOD); + retval=setSynchronization(arg); + } + if (retval==GET_SYNCHRONIZATION_MODE) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int read_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + //char *retval=NULL; + short int CounterVals[NCHAN*NCHIP]; + + sprintf(mess,"Read counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef PROPIXD + sprintf(mess,"can't read counter block for propix\n"); + ret = FAIL; +#endif + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + ret=readCounterBlock(startACQ,CounterVals); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,CounterVals[i]); +#endif + } + } + + if(ret!=FAIL){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,CounterVals,dataBytes);//1280*2 + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + + + +int reset_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + + sprintf(mess,"Reset counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=resetCounterBlock(startACQ); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + + /*return ok/fail*/ + return ret; +} + + + + + + +int start_receiver(int file_des) { + int ret=OK; + int n=0; + strcpy(mess,"Could not start receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret = startReceiver(1); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + + +int stop_receiver(int file_des) { + int ret=OK; + int n=0; + + strcpy(mess,"Could not stop receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret=startReceiver(0); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + +int calibrate_pedestal(int file_des){ + + int ret=OK; + int retval=-1; + int n; + int frames; + + sprintf(mess,"Could not calibrate pedestal\n"); + + n = receiveDataOnly(file_des,&frames,sizeof(frames)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=calibratePedestal(frames); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + + /*return ok/fail*/ + return ret; +} + + diff --git a/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h new file mode 100755 index 000000000..890c7452d --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/server_funcs.h @@ -0,0 +1,97 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H + + +#include "sls_detector_defs.h" + + +#include +/* +#include +#include +#include +*/ +#include "communication_funcs.h" + + + + +#define GOODBYE -200 + +int sockfd; + +int function_table(); + +int decode_function(int); +int init_detector(int); + +int M_nofunc(int); +int exit_server(int); + + + + +// General purpose functions +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); + + +int exec_command(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +int write_register(int); +int read_register(int); +int set_dac(int); +int get_adc(int); +int set_channel(int); +int set_chip(int); +int set_module(int); +int get_channel(int); +int get_chip(int); +int get_module(int); + +int get_threshold_energy(int); +int set_threshold_energy(int); +int set_settings(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int read_frame(int); +int read_all(int); +int start_and_read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_roi(int); +int get_roi(int); +int set_speed(int); +void prepareADC(void); +int set_readout_flags(int); +int execute_trimming(int); +int lock_server(int); +int set_port(int); +int get_last_client_ip(int); +int set_master(int); +int set_synchronization(int); + +int update_client(int); +int send_update(int); +int configure_mac(int); + +int load_image(int); +int read_counter_block(int); +int reset_counter_block(int); + +int start_receiver(int); +int stop_receiver(int); + + +int calibrate_pedestal(int); + +int set_roi(int); + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.c b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.c new file mode 100755 index 000000000..4504cfe05 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.c @@ -0,0 +1,39 @@ +#include "sharedmemory.h" + +struct statusdata *stdata; + +int inism(int clsv) { + +static int scansmid; + + if (clsv==SMSV) { + if ( (scansmid=shmget(SMKEY,1024,IPC_CREAT | 0666 ))==-1 ) { + return -1; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -2; + } + } + + if (clsv==SMCL) { + if ( (scansmid=shmget(SMKEY,0,0) )==-1 ) { + return -3; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -4; + } + } + return 1; +} + +void write_status_sm(char *status) { + strcpy(stdata->status,status); +} + +void write_stop_sm(int v) { + stdata->stop=v; +} + +void write_runnumber_sm(int v) { + stdata->runnumber=v; +} diff --git a/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.h b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.h new file mode 100755 index 000000000..bdbddf719 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sharedmemory.h @@ -0,0 +1,48 @@ +#ifndef SM +#define SM + +#include "sls_detector_defs.h" + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +/* key for shared memory */ +#define SMKEY 10001 + +#define SMSV 1 +#define SMCL 2 + + +struct statusdata { + int runnumber; + int stop; + char status[20]; +} ; + + +/* for shared memory */ + +int inism(int clsv); +void write_status_sm(char *status); +void write_stop_sm(int v); +void write_runnumber_sm(int v); + +#endif diff --git a/slsDetectorSoftware/gotthardDetectorServer/sls_detector_defs.h b/slsDetectorSoftware/gotthardDetectorServer/sls_detector_defs.h new file mode 120000 index 000000000..c5062e03f --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sls_detector_defs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/sls_detector_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/sls_detector_funcs.h new file mode 120000 index 000000000..844b67129 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sls_detector_funcs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/sls_receiver_defs.h b/slsDetectorSoftware/gotthardDetectorServer/sls_receiver_defs.h new file mode 120000 index 000000000..1de31caf5 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sls_receiver_defs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/sls_receiver_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/sls_receiver_funcs.h new file mode 120000 index 000000000..c2ea4ded9 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/sls_receiver_funcs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/gotthardDetectorServer/stop_server.c b/slsDetectorSoftware/gotthardDetectorServer/stop_server.c new file mode 100755 index 000000000..e3c8ff7e1 --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/stop_server.c @@ -0,0 +1,46 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + + +#include "sls_detector_defs.h" + + +#include "communication_funcs.h" +#include "firmware_funcs.h" + + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + + portno = DEFAULT_PORTNO; + + + bindSocket(portno); + if (getServerError()) + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + acceptConnection(); + retval=stopStateMachine(); + closeConnection(); + } + + exitServer(); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.c b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.c new file mode 100755 index 000000000..9a28b9b4a --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.c @@ -0,0 +1,749 @@ +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "trimming_funcs.h" +#include "mcb_funcs.h" +#include "firmware_funcs.h" +#include + + + +extern int nModX; +//extern int *values; + +extern const int nChans; +extern const int nChips; +extern const int nDacs; +extern const int nAdcs; + + +int trim_fixed_settings(int countlim, int par2, int im) +{ + + int retval=OK; +#ifdef VERBOSE + printf("Trimming with fixed settings\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + if (par2<=0) + retval=trim_with_level(countlim, im); + else + retval=trim_with_median(countlim,im); + + + return retval; +} + + +int trim_with_noise(int countlim, int nsigma, int im) +{ + + + int retval=OK, retval1=OK, retval2=OK; +#ifdef VERBOSE + printf("Trimming using noise\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + /* threshold scan */ + +#ifdef VERBOSE + printf("chosing vthresh and vtrim....."); +#endif + retval1=choose_vthresh_and_vtrim(countlim,nsigma, im); + +#ifdef VERBOSE + printf("trimming with noise.....\n"); +#endif + retval2=trim_with_level(countlim, im); + +#ifdef DEBUGOUT + printf("done\n"); +#endif + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + +int trim_with_beam(int countlim, int nsigma, int im) //rpc +{ + + + int retval=OK, retval1=OK, retval2=OK; + + printf("Trimming using beam\n"); + //return OK; +#ifdef VIRTUAL + printf("Trimming using beam\n"); + return OK; +#endif + /* threshold scan */ +#ifdef DEBUGOUT + printf("chosing vthresh and vtrim....."); +#endif + + retval1=choose_vthresh_and_vtrim(countlim,nsigma,im); + retval2=trim_with_median(TRIM_DR, im); + +#ifdef DEBUGOUT + printf("done\n"); +#endif + + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + + +int trim_improve(int maxit, int par2, int im) //rpc +{ + + int retval=OK, retval1=OK, retval2=OK; + + +#ifdef VERBOSE + printf("Improve the trimming\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + + if (par2!=0 && im==ALLMOD) + retval1=choose_vthresh(); + + retval2=trim_with_median(2*maxit+1, im); +#ifdef DEBUGOUT + printf("done\n"); +#endif + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + +int calcthr_from_vcal(int vcal) { + int thrmin; + //thrmin=140+3*vcal/5; + thrmin=180+3*vcal/5; + return thrmin; +} + +int calccal_from_vthr(int vthr) { + int vcal; + vcal=5*(vthr-140)/3; + return vcal; +} + +int choose_vthresh_and_vtrim(int countlim, int nsigma, int im) { + int retval=OK; +#ifdef MCB_FUNCS + int modma, modmi, nm; + int thr, thrstep=5, nthr=31; + + int *fifodata; + + double vthreshmean, vthreshSTDev; + int *thrmi, *thrma; + double c; + double b=BVTRIM; + double a=AVTRIM; + int *trim; + int ich, imod, ichan; + int nvalid=0; + u_int32_t *scan; + int ithr; + sls_detector_channel myChan; + + + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + trim=malloc(sizeof(int)*nChans*nChips*nModX); + thrmi=malloc(sizeof(int)*nModX); + thrma=malloc(sizeof(int)*nModX); + + + for (ich=0; ichcountlim && trim[ich]==-1) { +//commented out by dhanya trim[ich]=getDACbyIndexDACU(VTHRESH,imod); +#ifdef VERBOSE + // printf("yes: %d %d %d\n",ich,ithr,scan[ich]); +#endif + } +#ifdef VERBOSE + /* else { + printf("no: %d %d %d\n",ich,ithr,scan[ich]); + }*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imodthrmi[imod] && trim[ich]0) { + vthreshmean=vthreshmean/nvalid; + //commented out by dhanya vthreshSTDev=sqrt((vthreshSTDev/nvalid)-vthreshmean*vthreshmean); + } else { + vthreshmean=thrmi[imod]; + vthreshSTDev=nthr*thrstep; + printf("No valid channel for module %d\n",imod); + retval=FAIL; + } + +#ifdef DEBUGOUT + printf("module= %d nvalid = %d mean=%f RMS=%f\n",imod, nvalid, vthreshmean,vthreshSTDev); +#endif + // *vthresh=round(vthreshmean-nsigma*vthreshSTDev); + thr=(int)(vthreshmean-nsigma*vthreshSTDev); + if (thr<0 || thr>(DAC_DR-1)) { + thr=thrmi[imod]/2; + printf("Can't find correct threshold for module %d\n",imod); + retval=FAIL; + } +//commented out by dhanya initDACbyIndexDACU(VTHRESH,thr,imod); +#ifdef VERBOSE + printf("vthresh=%d \n",thr); +#endif + c=CVTRIM-2.*nsigma*vthreshSTDev/63.; + //commented out by dhanya thr=(int)((-b-sqrt(b*b-4*a*c))/(2*a)); + if (thr<500 || thr>(DAC_DR-1)) { + thr=750; + printf("Can't find correct trimbit size for module %d\n",imod); + retval=FAIL; + } + + //commented out by dhanya initDACbyIndexDACU(VTRIM,thr,imod); + +#ifdef VERBOSE + printf("vtrim=%d \n",thr); +#endif + + } + free(trim); + free(thrmi); + free(thrma); + +#endif + return retval; +} + + + + + +int trim_with_level(int countlim, int im) { + int ich, itrim, ichan, ichip, imod; + u_int32_t *scan; + int *inttrim; + int modma, modmi, nm; + int retval=OK; + int *fifodata; + sls_detector_channel myChan; + printf("trimming module number %d", im); + + +#ifdef MCB_FUNCS + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + inttrim=malloc(sizeof(int)*nChips*nChans*nModX); + printf("countlim=%d\n",countlim); + for (ich=0; ichcountlim){ + inttrim[ich]=itrim; + if (scan[ich]>2*countlim && itrim>0) { + //if (scan[ich]>2*countlim || itrim==0) { + inttrim[ich]=itrim-1; + } +#ifdef VERBOSE + printf("Channel %d trimbit %d counted %d (%08x) countlim %d\n",ich,itrim,scan[ich],fifodata[ich],countlim); +#endif + } + } +#ifdef VERBOSE + /* else + printf("Channel %d trimbit %d counted %d countlim %d\n",ich,itrim,scan[ich],countlim);*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imod0) + direction[ichan]=1; + else + direction[ichan]=-1; + } + //commented out by dhanya vthresh=getDACbyIndexDACU(VTHRESH,imod); + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + vthresh=vthresh-direction[ichan]; + if (vthresh>(DAC_DR-1)) { + vthresh=(DAC_DR-1); + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + if (vthresh<0) { + vthresh=0; + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + direction[ichan]=-3; + } else { + vthresh=vthresh+direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } +//commented out by dhanya initDACbyIndex(VTHRESH,vthresh, ichan); + } + } + iteration++; + free(scan); + free(scan1); + } +#endif + return retval; +} + + + + + +int trim_with_median(int stop, int im) { + + + int retval=OK; + +#ifdef MCB_FUNCS + int ichan, imod, ichip, ich; + u_int32_t *scan, *scan1; + int *olddiff, *direction; + int med, diff; + int change_flag=1; + int iteration=0; + int me[nModX], me1[nModX]; + int modma, modmi, nm; + int trim; + int *fifodata; + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + olddiff=malloc(4*nModX*nChips*nChans); + direction=malloc(4*nModX*nChips*nChans); + for (imod=modmi; imod0) { + direction[ichan]=1; + } else { + direction[ichan]=-1; + } + } + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + trim=getTrimbit(imod,ichip,ich)+direction[ichan]; + printf("%d old diff %d < new diff %d %d - trimbit %d\n",ichan, olddiff[ichan], diff, direction[ichan], trim); + direction[ichan]=-3; + } else { + trim=getTrimbit(imod,ichip,ich)-direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } + if (trim>TRIM_DR) { + trim=63; + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + retval=FAIL; + } + if (trim<0) { + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + trim=0; + retval=FAIL; + } + initChannel(trim,0,0,1,0,0,imod); + } + } + } + } + iteration++; + free(scan); + free(scan1); + } + free(olddiff); + free(direction); +#endif + return retval; +} diff --git a/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.h b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.h new file mode 100755 index 000000000..42ecea24a --- /dev/null +++ b/slsDetectorSoftware/gotthardDetectorServer/trimming_funcs.h @@ -0,0 +1,20 @@ +#ifndef TRIMMING_FUNCS_H +#define TRIMMING_FUNCS_H + +#include "sls_detector_defs.h" + +int trim_fixed_settings(int countlim, int par2, int imod); +int trim_with_noise(int countlim, int nsigma, int imod); +int trim_with_beam(int countlim, int nsigma, int imod); +int trim_improve(int maxit, int par2, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); +int choose_vthresh_and_vtrim(int countlim, int nsigma, int imod); + +int choose_vthresh(); +int trim_with_level(int countlim, int imod); +int trim_with_median(int stop, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); + +#endif diff --git a/slsDetectorSoftware/include/detectorData.h b/slsDetectorSoftware/include/detectorData.h new file mode 120000 index 000000000..44205ed04 --- /dev/null +++ b/slsDetectorSoftware/include/detectorData.h @@ -0,0 +1 @@ +../slsDetectorAnalysis/detectorData.h \ No newline at end of file diff --git a/slsDetectorSoftware/include/slsDetectorUsers.h b/slsDetectorSoftware/include/slsDetectorUsers.h new file mode 120000 index 000000000..51e196881 --- /dev/null +++ b/slsDetectorSoftware/include/slsDetectorUsers.h @@ -0,0 +1 @@ +../slsDetector/slsDetectorUsers.h \ No newline at end of file diff --git a/slsDetectorSoftware/include/slsReceiverUsers.h b/slsDetectorSoftware/include/slsReceiverUsers.h new file mode 120000 index 000000000..d73c332c0 --- /dev/null +++ b/slsDetectorSoftware/include/slsReceiverUsers.h @@ -0,0 +1 @@ +../slsReceiver/slsReceiverUsers.h \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/Makefile.ctb b/slsDetectorSoftware/jctbDetectorServer/Makefile.ctb new file mode 100644 index 000000000..ca00d71b9 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/Makefile.ctb @@ -0,0 +1,61 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + + +CROSS = bfin-uclinux- +CC = $(CROSS)gcc + +CFLAGS += -Wall -DMOENCHD -DMCB_FUNCS -DDACS_INT -DDEBUG -DV1 -DCTB #-DVERBOSE #-DVERYVERBOSE #-DVIRTUAL #-DDACS_INT_CSERVER + + +PROGS= jungfrauDetectorServerTest +INSTDIR= /tftpboot +INSTMODE= 0777 + + + +BINS = testlib_sharedlibc +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + + + +all: clean $(PROGS) + +test: clean jungfrauADCTEst + +boot: $(OBJS) + +jungfrauDetectorServerTest: $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +jungfrauDetectorServer: $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + +jungfrauADCTEst: $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) -DTESTADC + + + + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + + +romfs: + $(ROMFSINST) /bin/$(PROGS) + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/jctbDetectorServer/ansi.h b/slsDetectorSoftware/jctbDetectorServer/ansi.h new file mode 120000 index 000000000..a122db0ad --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/ansi.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/communication_funcs.c b/slsDetectorSoftware/jctbDetectorServer/communication_funcs.c new file mode 120000 index 000000000..87a4f95d1 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/communication_funcs.c @@ -0,0 +1 @@ +../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/communication_funcs.h b/slsDetectorSoftware/jctbDetectorServer/communication_funcs.h new file mode 120000 index 000000000..f220903b2 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/communication_funcs.h @@ -0,0 +1 @@ +../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c b/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c new file mode 100755 index 000000000..0b623c757 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/firmware_funcs.c @@ -0,0 +1,3664 @@ +//#define TESTADC +#define TESTADC1 + + +//#define TIMEDBG +#include "server_defs.h" +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers_m.h" + +//#define VERBOSE +//#define VERYVERBOSE + + +#ifdef SHAREDMEMORY +#include "sharedmemory.h" +#endif + +#include +#include +#include + +#include +#include +#include /* exit() */ +#include /* memset(), memcpy() */ +#include /* uname() */ +#include +#include /* socket(), bind(), + listen(), accept() */ +#include +#include +#include +#include +#include /* fork(), write(), close() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct ip_header_struct { + u_int16_t ip_len; + u_int8_t ip_tos; + u_int8_t ip_ihl:4 ,ip_ver:4; + u_int16_t ip_offset:13,ip_flag:3; + u_int16_t ip_ident; + u_int16_t ip_chksum; + u_int8_t ip_protocol; + u_int8_t ip_ttl; + u_int32_t ip_sourceip; + u_int32_t ip_destip; +} ip_header; + + +struct timeval tss,tse,tsss; //for timing + + +//for memory mapping +u_int32_t CSP0BASE; + + +FILE *debugfp, *datafp; + +int fr; +int wait_time; +int *fifocntrl; + +//int *statusreg; commented out by dhanya +const int nModY=1; +int nModBoard; +int nModX=NMAXMOD; +int dynamicRange=16;//32; +int nSamples=1; + +int dataBytes=NMAXMOD*NCHIP*NCHAN*2; + +int storeInRAM=0; +int ROI_flag=0; +int adcConfigured=-1; +u_int16_t *ram_values=NULL; +char volatile *now_ptr=NULL; +//u_int32_t volatile *values; +u_int16_t volatile *values; +int ram_size=0; + +int64_t totalTime=1; +u_int32_t progressMask=0; + +int phase_shift=0;//DEFAULT_PHASE_SHIFT; +int ipPacketSize=DEFAULT_IP_PACKETSIZE; +int udpPacketSize=DEFAULT_UDP_PACKETSIZE; + +#ifndef NEW_PLL_RECONFIG +u_int32_t clkDivider[2]={32,16}; +#else +u_int32_t clkDivider[2]={40,20}; +#endif +int32_t clkPhase[2]={0,0}; + +u_int32_t adcDisableMask=0; + +int ififostart, ififostop, ififostep, ififo; + +int masterMode=NO_MASTER, syncMode=NO_SYNCHRONIZATION, timingMode=AUTO_TIMING; + +enum externalSignalFlag signals[4]={EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF}; + +int withGotthard = 0; + +/**is not const because this value will change after initDetector, is removed from mcb_funcs.c cuz its not used anywhere + * why is this used anywhere instead of macro*/ +int nChans=NCHAN; +int nChips=NCHIP; +int nDacs=NDAC; +int nAdcs=NADC; + +extern enum detectorType myDetectorType; +/** for jungfrau reinitializing macro later in server_funcs.c in initDetector*/ +extern int N_CHAN; +extern int N_CHIP; +extern int N_DAC; +extern int N_ADC; +extern int N_CHANS; + +int mapCSP0(void) { + printf("Mapping memory\n"); +#ifndef VIRTUAL + int fd; + fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + printf("\nCan't find /dev/mem!\n"); + return FAIL; + } + printf("/dev/mem opened\n"); + + CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + printf("\nCan't map memmory area!!\n"); + return FAIL; + } + printf("CSP0 mapped\n"); + +#endif +#ifdef VIRTUAL + CSP0BASE = malloc(MEM_SIZE); + printf("memory allocated\n"); +#endif +#ifdef SHAREDMEMORY + if ( (res=inism(SMSV))<0) { + printf("error attaching shared memory! %i",res); + return FAIL; + } +#endif + printf("CSPObase is 0x%08x \n",CSP0BASE); + printf("CSPOBASE=from %08x to %08x\n",CSP0BASE,CSP0BASE+MEM_SIZE); + + u_int32_t address; + address = FIFO_DATA_REG;//_OFF; + //values=(u_int32_t*)(CSP0BASE+address*2); + values=(u_int16_t*)(CSP0BASE+address*2); + printf("statusreg=%08x\n",bus_r(STATUS_REG)); + printf("\n\n"); + return OK; +} + +u_int16_t bus_r16(u_int32_t offset){ + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + return *ptr1; +} + +u_int16_t bus_w16(u_int32_t offset, u_int16_t data) { + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + *ptr1=data; + return OK; +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_w16(u_int32_t ramType, int adc, int adcCh, int Ch, u_int16_t data) { + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Writing to addr:%x\n",adr); + return bus_w16(adr,data); +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_r16(u_int32_t ramType, int adc, int adcCh, int Ch){ + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Reading from addr:%x\n",adr); + return bus_r16(adr); +} + +u_int32_t bus_w(u_int32_t offset, u_int32_t data) { + volatile u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + *ptr1=data; + + return OK; +} + + +u_int32_t bus_r(u_int32_t offset) { + volatile u_int32_t *ptr1; + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + return *ptr1; +} + + +int setPhaseShiftOnce(){ + u_int32_t addr, reg; + int i; + addr=MULTI_PURPOSE_REG; + reg=bus_r(addr); +#ifdef VERBOSE + printf("Multipurpose reg:%x\n",reg); +#endif + + //Checking if it is power on(negative number) + // if(((reg&0xFFFF0000)>>16)>0){ + //bus_w(addr,0x0); //clear the reg + + if(reg==0){ + printf("\nImplementing phase shift of %d\n",phase_shift); + for (i=1;i2*l) { + h=l+1; + odd=1; + } + printf("Counter %d: Low is %d, High is %d\n",i, l,h); + + + val= (i<<18)| (odd<<17) | l | (h<<8); + + printf("Counter %d, val: %08x\n", i, val); + setPllReconfigReg(PLL_C_COUNTER_REG, val,0); + // usleep(20); + //change sync at the same time as + if (i>0) { + val= (2<<18)| (odd<<17) | l | (h<<8); + + printf("Counter %d, val: %08x\n", i, val); + setPllReconfigReg(PLL_C_COUNTER_REG, val,0); + + } + + } else { + // if (mode==1) { + // } else { + printf("phase in %d\n",clkPhase[1]); + + if (clkPhase[1]>0) { + inv=0; + phase=clkPhase[1]; + } else { + inv=1; + phase=-1*clkPhase[1]; + } + + printf("phase out %d %08x\n",phase,phase); + if (inv) { + val=phase | (1<<16);// | (inv<<21); + printf("**************** phase word %08x\n",val); + + // printf("Phase, val: %08x\n", val); + setPllReconfigReg(PLL_PHASE_SHIFT_REG,val,0); //shifts counter 0 + } else { + + + val=phase ;// | (inv<<21); + printf("**************** phase word %08x\n",val); + + // printf("Phase, val: %08x\n", val); + setPllReconfigReg(PLL_PHASE_SHIFT_REG,val,0); //shifts counter 0 +#ifndef NEW_PLL_RECONFIG + printf("Start reconfig\n"); setPllReconfigReg(PLL_START_REG, 1,0); + + // bus_w(PLL_CNTRL_REG, 0); + printf("Status register\n"); getPllReconfigReg(PLL_STATUS_REG,0); + // sleep(1); + + printf("PLL mode\n"); setPllReconfigReg(PLL_MODE_REG,1,0); + // usleep(10000); + +#endif + printf("**************** phase word %08x\n",val); + + val=phase | (2<<16);// | (inv<<21); + // printf("Phase, val: %08x\n", val); + setPllReconfigReg(PLL_PHASE_SHIFT_REG,val,0); //shifts counter 0 + } + + + } + +#ifndef NEW_PLL_RECONFIG + printf("Start reconfig\n"); setPllReconfigReg(PLL_START_REG, 1,0); + + // bus_w(PLL_CNTRL_REG, 0); + printf("Status register\n"); getPllReconfigReg(PLL_STATUS_REG,0); + // sleep(1); +#endif + // printf("PLL mode\n"); setPllReconfigReg(PLL_MODE_REG,0,0); + usleep(10000); + if (i<2) { + printf("reset pll\n"); + bus_w(PLL_CNTRL_REG,((1<1) + return -1; + + if (ic==1 && d>40) + return -1; + + if (d>160) + return -1; + + if (tot>510) + return -1; + + if (tot<1) + return -1; + + + + clkDivider[ic]=d; + configurePll(ic); + + + + return clkDivider[ic]; +} + + +int phaseStep(int st){ + + if (st>65535 || st<-65535) + return clkPhase[0]; +#ifdef NEW_PLL_RECONFIG + printf("reset pll\n"); + bus_w(PLL_CNTRL_REG,((1<1) + return -1; + return clkDivider[ic]; + + +/* int ic=0; */ +/* u_int32_t val; */ +/* u_int32_t l,h; */ + +/* printf("get clk divider\n"); */ + + +/* setPllReconfigReg(PLL_MODE_REG,1,0); */ +/* getPllReconfigReg(PLL_MODE_REG,0); */ + +/* u_int32_t addr=0xa; //c0 */ +/* if (ic>0) */ +/* addr=0xb; //c1 */ + +/* val=getPllReconfigReg(PLL_N_COUNTER_REG,0); */ +/* printf("Getting N counter %08x\n",val); */ + +/* l=val&0xff; */ +/* h=(val>>8)&0xff; */ + +/* //getPllReconfigReg(PLL_STATUS_REG,0); */ +/* val=getPllReconfigReg(addr,0); */ +/* printf("Getting C counter %08x\n",val); */ + + + +/* return 800/(l+h); */ + +} + + +u_int32_t adcPipeline(int d) { + if (d>=0) + bus_w(DAQ_REG, d); + return bus_r(DAQ_REG)&0xff; +} + + +u_int32_t setSetLength(int d) { + return 0; +} + +u_int32_t getSetLength() { + return 0; +} + +u_int32_t setOversampling(int d) { + + if (d>=0 && d<=255) + bus_w(OVERSAMPLING_REG, d); + + return bus_r(OVERSAMPLING_REG); +} + + +u_int32_t setWaitStates(int d1) { + return 0; +} + +u_int32_t getWaitStates() { + return 0; +} + + +u_int32_t setTotClockDivider(int d) { + return 0; +} + +u_int32_t getTotClockDivider() { + return 0; +} + + +u_int32_t setTotDutyCycle(int d) { + return 0; +} + +u_int32_t getTotDutyCycle() { + return 0; +} + + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode) { + + //int modes[]={EXT_SIG_OFF, EXT_GATE_IN_ACTIVEHIGH, EXT_GATE_IN_ACTIVELOW,EXT_TRIG_IN_RISING,EXT_TRIG_IN_FALLING,EXT_RO_TRIG_IN_RISING, EXT_RO_TRIG_IN_FALLING,EXT_GATE_OUT_ACTIVEHIGH, EXT_GATE_OUT_ACTIVELOW, EXT_TRIG_OUT_RISING, EXT_TRIG_OUT_FALLING, EXT_RO_TRIG_OUT_RISING, EXT_RO_TRIG_OUT_FALLING}; + // int off=d*SIGNAL_OFFSET; + + u_int32_t c; + c=bus_r(EXT_SIGNAL_REG); + + if (d>=0 && d<4) { + signals[d]=mode; +#ifdef VERBOSE + printf("settings signal variable number %d to value %04x\n", d, signals[d]); +#endif + + // if output signal, set it! + + switch (mode) { + case GATE_IN_ACTIVE_HIGH: + case GATE_IN_ACTIVE_LOW: + if (timingMode==GATE_FIX_NUMBER || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case TRIGGER_IN_RISING_EDGE: + case TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_EXPOSURE || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case RO_TRIGGER_IN_RISING_EDGE: + case RO_TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_READOUT) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case MASTER_SLAVE_SYNCHRONIZATION: + setSynchronization(syncMode); + break; + default: + setFPGASignal(d,mode); + break; + } + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + } + + +// if (mode<=RO_TRIGGER_OUT_FALLING_EDGE && mode>=0) +// bus_w(EXT_SIGNAL_REG,((modes[mode])<=0) { +#ifdef VERBOSE + printf("writing signal register number %d mode %04x\n",d, modes[mode]); +#endif + bus_w(EXT_SIGNAL_REG,((modes[mode])<>off); + + if (mode=0 && d<4) { +#ifdef VERBOSE + printf("gettings signal variable number %d value %04x\n", d, signals[d]); +#endif + return signals[d]; + } else + return -1; + + +} + + +int getFPGASignal(int d) { + + int modes[]={SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW,TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE,RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE,RO_TRIGGER_OUT_FALLING_EDGE}; + + int off=d*SIGNAL_OFFSET; + int mode=((bus_r(EXT_SIGNAL_REG)&(SIGNAL_MASK<>off); + + if (mode<=RO_TRIGGER_OUT_FALLING_EDGE) { + if (modes[mode]!=SIGNAL_OFF && signals[d]!=MASTER_SLAVE_SYNCHRONIZATION) + signals[d]=modes[mode]; +#ifdef VERYVERBOSE + printf("gettings signal register number %d value %04x\n", d, modes[mode]); +#endif + return modes[mode]; + } else + return -1; + +} + + + + + +/* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; +*/ + + +int setTiming(int ti) { + + + int ret=GET_EXTERNAL_COMMUNICATION_MODE; + + int g=-1, t=-1, rot=-1; + + int i; + + switch (ti) { + case AUTO_TIMING: + timingMode=ti; + // disable all gates/triggers in except if used for master/slave synchronization + for (i=0; i<4; i++) { + if (getFPGASignal(i)>0 && getFPGASignal(i)=0 && t>=0 && rot<0) { + ret=GATE_WITH_START_TRIGGER; + } else if (g<0 && t>=0 && rot<0) { + ret=TRIGGER_EXPOSURE; + } else if (g>=0 && t<0 && rot<0) { + ret=GATE_FIX_NUMBER; + } else if (g<0 && t<0 && rot>0) { + ret=TRIGGER_READOUT; + } else if (g<0 && t<0 && rot<0) { + ret=AUTO_TIMING; + } + + // timingMode=ret; + + return ret; + +} + + + +int setConfigurationRegister(int d) { +#ifdef VERBOSE + printf("Setting configuration register to %x",d); +#endif + if (d>=0) { + bus_w(CONFIG_REG,d); + } +#ifdef VERBOSE + printf("configuration register is %x", bus_r(CONFIG_REG)); +#endif + return bus_r(CONFIG_REG); +} + +int setToT(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting ToT to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: ToT is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|TOT_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~TOT_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("ToT is %x\n", reg); +#endif + if (reg&TOT_ENABLE_BIT) + return 1; + else + return 0; +} + +int setContinousReadOut(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting Continous readout to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: Continous readout is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|CONT_RO_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~CONT_RO_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Continous readout is %x\n", reg); +#endif + if (reg&CONT_RO_ENABLE_BIT) + return 1; + else + return 0; +} + + +int startReceiver(int start) { + u_int32_t addr=CONFIG_REG; +#ifdef VERBOSE + if(start) + printf("Setting up detector to send to Receiver\n"); + else + printf("Setting up detector to send to CPU\n"); +#endif + int reg=bus_r(addr); + //for start recever, write 0 and for stop, write 1 + if (!start) + bus_w(CONFIG_REG,reg&(~GB10_NOT_CPU_BIT)); + else + bus_w(CONFIG_REG,reg|GB10_NOT_CPU_BIT); + + reg=bus_r(addr); +//#ifdef VERBOSE + printf("Config Reg %x\n", reg); +//#endif + int d =reg&GB10_NOT_CPU_BIT; + if(d!=0) d=1; + if(d!=start) + return OK; + else + return FAIL; +} + + +u_int64_t getDetectorNumber() { + char output[255],mac[255]=""; + u_int64_t res=0; + FILE* sysFile = popen("ifconfig eth0 | grep HWaddr | cut -d \" \" -f 11", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + //getting rid of ":" + char * pch; + pch = strtok (output,":"); + while (pch != NULL){ + strcat(mac,pch); + pch = strtok (NULL, ":"); + } + sscanf(mac,"%llx",&res); + return res; +} + +u_int32_t getFirmwareVersion() { + return bus_r(FPGA_VERSION_REG); +} + +u_int32_t getFirmwareSVNVersion(){ + return bus_r(FPGA_SVN_REG); +} + + +// for fpga test +u_int32_t testFpga(void) { + printf("Testing FPGA:\n"); + volatile u_int32_t val,addr,val2; + int result=OK,i; + //fixed pattern + val=bus_r(FIX_PATT_REG); + if (val==FIXED_PATT_VAL) { + printf("fixed pattern ok!! %08x\n",val); + } else { + printf("fixed pattern wrong!! %08x\n",val); + result=FAIL; + } + + //dummy register + addr = DUMMY_REG; + for(i=0;i<1000000;i++) + { + val=0x5A5A5A5A-i; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x5A5A5A5A-i) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of %x \n",i,val,0x5A5A5A5A-i); + result=FAIL; + } + val=(i+(i<<10)+(i<<20)); + bus_w(addr, val); + val2=bus_r(addr); + if (val2!=val) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! read %x instead of %x.\n",i,val2,val); + result=FAIL; + } + val=0x0F0F0F0F; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x0F0F0F0F) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0x0F0F0F0F \n",i,val); + result=FAIL; + } + val=0xF0F0F0F0; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0xF0F0F0F0) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0xF0F0F0F0 \n\n",i,val); + result=FAIL; + } + } + if(result==OK) + { + printf("----------------------------------------------------------------------------------------------"); + printf("\nATTEMPT 1000000: FPGA DUMMY REGISTER OK!!!\n"); + printf("----------------------------------------------------------------------------------------------"); + } + printf("\n"); + return result; +} + + +// for fpga test +u_int32_t testRAM(void) { + int result=OK; + + printf("TestRAM not implemented\n"); + +/* int i=0; + allocateRAM(); + // while(i<100000) { + memcpy(ram_values, values, dataBytes); + printf ("Testing RAM:\t%d: copied fifo %x to memory %x size %d\n",i++, (unsigned int)(values), (unsigned int)(ram_values), dataBytes); + // } + * +*/ + return result; +} + + +int getNModBoard() { +if(myDetectorType == JUNGFRAU) + return 1; +else + return 32;//nModX; +} + +int setNMod(int n) { + +/* printf("Writin ADC disable register %08x\n",n); */ +/* bus_w(ADC_LATCH_DISABLE_REG,n); */ + return getNMod(); +} + +int getNMod() { +/* u_int32_t reg; */ +/* int i; */ +/* reg=bus_r(ADC_LATCH_DISABLE_REG); */ + +/* printf("Read ADC disable register %08x\n",reg); */ +/* nModX=32; */ +/* for (i=0; i<32; i++) { */ +/* if (reg & (1<> 32; + vMSB=v64&(0xffffffff); + bus_w(aMSB,vMSB); + } + return get64BitReg(aLSB, aMSB); + +} + +int64_t get64BitReg(int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + vLSB=bus_r(aLSB); + vMSB=bus_r(aMSB); + v64=vMSB; + v64=(v64<<32) | vLSB; + + printf("reg64(%x,%x) %x %x %llx\n", aLSB, aMSB, vLSB, vMSB, v64); + + return v64; +} + +int64_t setFrames(int64_t value){ + return set64BitReg(value, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); +} + +int64_t getFrames(){ + /*printf("gf");*/ + return get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); +} + +int64_t setExposureTime(int64_t value){ + /* time is in ns */ + if (value!=-1) + value*=(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); + return set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t getExposureTime(){ + return get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t setGates(int64_t value){ + return set64BitReg(value, SET_GATES_LSB_REG, SET_GATES_MSB_REG); +} + +int64_t getGates(){ + return get64BitReg(GET_GATES_LSB_REG, GET_GATES_MSB_REG); +} + +int64_t setPeriod(int64_t value){ + /* time is in ns */ + if (value!=-1) { + // value*=(1E-9*CLK_FREQ); + value*=(1E-3*clkDivider[1]); + } + if (value%2==0) { + + printf("Adding one to period: was %08llx ", value); + value+=1; + printf("now is %08llx\n ", value); + + + } else + printf("Period already even is %08llx\n ", value); + + + return set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t getPeriod(){ + return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t setDelay(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-3*clkDivider[1]);//(1E-9*CLK_FREQ); + } + return set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t getDelay(){ + return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t setTrains(int64_t value){ + return set64BitReg(value, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); +} + +int64_t getTrains(){ + return get64BitReg(GET_CYCLES_LSB_REG, GET_CYCLES_MSB_REG); +} + + +int64_t setProbes(int64_t value){ + return 0; +} + + +int64_t setProgress() { + + //????? eventually call after setting the registers + +return 0; + +} + + +int64_t getProgress() { + + + //should be done in firmware!!!! + + return 0; + +} + +int64_t getActualTime(){ + return get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getMeasurementTime(){ + int64_t v=get64BitReg(GET_MEASUREMENT_TIME_LSB_REG, GET_MEASUREMENT_TIME_MSB_REG); + // int64_t mask=0x8000000000000000; + // if (v & mask ) { + //#ifdef VERBOSE + // printf("no measurement time left\n"); + //#endif + // return -1E+9; + // } else + return v/(1E-9*CLK_FREQ); +} + +int64_t getFramesFromStart(){ + int64_t v=get64BitReg(FRAMES_FROM_START_LSB_REG, FRAMES_FROM_START_MSB_REG); + int64_t v1=get64BitReg(FRAMES_FROM_START_PG_LSB_REG, FRAMES_FROM_START_PG_MSB_REG); + + printf("Frames from start data streaming %lld\n",v); + printf("Frames from start run control %lld\n",v1); + + // int64_t mask=0x8000000000000000; + // if (v & mask ) { + //#ifdef VERBOSE + // printf("no measurement time left\n"); + //#endif + // return -1E+9; + // } else + return v; +} + + +ROI *setROI(int nroi,ROI* arg,int *retvalsize, int *ret) { + + if(myDetectorType == JUNGFRAU) + cprintf(RED,"ROI Not implemented for Jungfrau yet\n"); + return NULL; + + + ROI retval[MAX_ROIS]; + int i, ich; + adcDisableMask=0xfffffffff; /*warning: integer constant is too large for ‘long’ type,warning: large integer implicitly truncated to unsigned type*/ + + printf("Setting ROI\n"); + if (nroi>=0) { + if (nroi==0) { + adcDisableMask=0; + } else { + for (i=0; i=0 && ichMAX_ROIS) { + *retvalsize-=1; + break; + } + retval[*retvalsize-1].xmin=ich; + retval[*retvalsize-1].xmax=ich; + } else { + if ((adcDisableMask)&(1<<(ich-1))) { + *retvalsize+=1; + if (*retvalsize>MAX_ROIS) { + *retvalsize-=1; + break; + } + retval[*retvalsize-1].xmin=ich; + } + retval[*retvalsize-1].xmax=ich; + } + } + } + getDynamicRange(); + return retval;/*warning: function returns address of local variable*/ + +} + + +int loadImage(int index, short int ImageVals[]){ + + printf("loadImage Not implemented yet\n"); + + /* + u_int32_t address; + switch (index) { + case DARK_IMAGE : + address = DARK_IMAGE_REG; + break; + case GAIN_IMAGE : + address = GAIN_IMAGE_REG; + break; + } + volatile u_int16_t *ptr; + ptr=(u_int16_t*)(CSP0BASE+address*2); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,ImageVals[i]); +#endif + memcpy(ptr,ImageVals ,dataBytes); +#ifdef VERBOSE + printf("\nLoaded x%08x address with image of index %d\n",(unsigned int)(ptr),index); +#endif + */ + + return OK; +} + + + +int64_t getProbes(){ + return 0; +} + + +int setDACRegister(int idac, int val, int imod) { +/* u_int32_t addr, reg, mask; */ +/* int off; */ +/* #ifdef VERBOSE */ +/* if(val==-1) */ +/* printf("Getting dac register%d module %d\n",idac,imod); */ +/* else */ +/* printf("Setting dac register %d module %d to %d\n",idac,imod,val); */ +/* #endif */ + +/* switch(idac){ */ +/* case 0: */ +/* case 1: */ +/* case 2: */ +/* addr=MOD_DACS1_REG; */ +/* break; */ +/* case 3: */ +/* case 4: */ +/* case 5: */ +/* addr=MOD_DACS2_REG; */ +/* break; */ +/* case 6: */ +/* case 7: */ +/* addr=MOD_DACS3_REG; */ +/* break; */ +/* default: */ +/* printf("weird idac value %d\n",idac); */ +/* return -1; */ +/* break; */ +/* } */ +/* //saving only the msb */ +/* val=val>>2; */ + +/* off=(idac%3)*10; */ +/* mask=~((0x3ff)<=0 && val>off)&0x3ff; */ +/* //since we saved only the msb */ +/* val=val<<2; */ + +/* //val=(bus_r(addr)>>off)&0x3ff; */ + + +/* #ifdef VERBOSE */ +/* printf("Dac %d module %d register is %d\n\n",idac,imod,val); */ +/* #endif */ +/* return val; */ +} + + +int getTemperature(int tempSensor, int imod){ + int val; + imod=0;//ignoring more than 1 mod for now + int i,j,repeats=6; + u_int32_t tempVal=0; +#ifdef VERBOSE + char cTempSensor[2][100]={"ADCs/ASICs","VRs/FPGAs"}; + printf("Getting Temperature of module:%d for the %s for tempsensor:%d\n",imod,cTempSensor[tempSensor],tempSensor); +#endif + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + bus_w(TEMP_IN_REG,((T1_CLK_BIT)&~(T1_CS_BIT))|(T2_CLK_BIT));//high clk low cs + + for(i=0;i<20;i++) { + //repeats is number of register writes for delay + for(j=0;j>1);//fpga + } + } + + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + val=((int)tempVal)/4.0; + +#ifdef VERBOSE + printf("Temperature of module:%d for the %s is %.2fC\n",imod,cTempSensor[tempSensor],val); +#endif + return val; +} + + + +int initHighVoltage(int val, int imod){ + + + u_int32_t offw,codata; + u_int16_t valw, dacvalue; + int iru,i,ddx,csdx,cdx; + float alpha=0.55, fval=val; + + if (val>=0) { + + if (val<60) { + dacvalue=0; + val=60; + } else if (val>=200) { + dacvalue=0x1; + val=200; + } else { + dacvalue=1.+(200.-val)/alpha; + val=200.-(dacvalue-1)*alpha; + } + printf ("****************************** setting val %d, dacval %d\n",val, dacvalue); + offw=DAC_REG; + + ddx=8; csdx=10; cdx=9; + codata=((dacvalue)&0xff); + + + + + valw=0xffff; bus_w(offw,(valw)); // start point + valw=((valw&(~(0x1<>(7-i))&0x1)< 1 ) { + sum += *addr++; + count -= 2; + } + if( count > 0 ) sum += *addr; // Add left-over byte, if any + while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);// Fold 32-bit sum to 16 bits + checksum = (~sum)&0xffff; + + printf("IP checksum is 0x%lx\n",checksum); + + return checksum; +} + + + +#ifdef NEW_GBE_INTERFACE +int writeGbeReg(int ivar, uint32_t val, int addr, int interface) { +/* #define GBE_CTRL_WSTROBE 0 */ +/* #define GBE_CTRL_VAR_OFFSET 16 */ +/* #define GBE_CTRL_VAR_MASK 0XF */ +/* #define GBE_CTRL_RAMADDR_OFFSET 24 */ +/* #define GBE_CTRL_RAMADDR_MASK 0X3F */ +/* #define GBE_CTRL_INTERFACE 23 */ + uint32_t ctrl=((ivar&GBE_CTRL_VAR_MASK)<>32)&0xFFFFFFFF; + vals[IPCHECKSUM_ADDR]=checksum; + vals[GBE_DELAY_ADDR]=0; + vals[GBE_RESERVED1_ADDR]=sourceport; + vals[GBE_RESERVED2_ADDR]=interface; + vals[DETECTOR_MAC_L_ADDR]=(sourcemac)&0xFFFFFFFF; + vals[DETECTOR_MAC_H_ADDR]=(sourcemac>>32)&0xFFFFFFFF; + vals[DETECTOR_IP_ADDR]=sourceip; + + for (ivar=0; ivar>32)&0xFFFFFFFF);//rx_udpmacH_AReg_c + bus_w(RX_UDPMACL_AREG,(destmac)&0xFFFFFFFF);//rx_udpmacL_AReg_c + bus_w(DETECTORMACH_AREG,(sourcemac>>32)&0xFFFFFFFF);//detectormacH_AReg_c + bus_w(DETECTORMACL_AREG,(sourcemac)&0xFFFFFFFF);//detectormacL_AReg_c + bus_w(UDPPORTS_AREG,((sourceport&0xFFFF)<<16)+(destport&0xFFFF));//udpports_AReg_c + bus_w(IPCHKSUM_AREG,(checksum&0xFFFF));//ipchksum_AReg_c + + +#endif + + bus_w(CONTROL_REG,GB10_RESET_BIT); + sleep(1); + bus_w(CONTROL_REG,0); + usleep(10000); + bus_w(CONFIG_REG,conf | GB10_NOT_CPU_BIT); + printf("System status register is %08x\n",bus_r(SYSTEM_STATUS_REG)); + +return 0; //any value doesnt matter - dhanya + +} + + + + + + + + + + + +int configureMAC(uint32_t destip,uint64_t destmac,uint64_t sourcemac,int sourceip,int ival,uint32_t destport) { +//int configureMAC(int ipad,long long int macad,long long int detectormacad, int detipad, int ival, int udpport){ + + uint32_t sourceport = 0x7e9a; // 0xE185; + int interface=0; + int ngb; +volatile u_int32_t conf= bus_r(CONFIG_REG); + + + + + +#ifdef NEW_GBE_INTERFACE + ngb=2; + printf("--------- New XGB interface\n"); +#else + ngb=1; + printf("********* Old XGB interface\n"); +#endif + + for (interface=0; interface >((i)*2))==3) { *\/ */ +/* /\* i++; *\/ */ +/* /\* if (i>15) *\/ */ +/* /\* break; *\/ */ +/* /\* } *\/ */ +/* /\* if (i<16) { *\/ */ +/* bus_w16(DUMMY_REG,i); */ +/* } */ +/* val=*values; */ + + + // bus_w16(DUMMY_REG,0); // + for (i=0; i<32; i++) { + + + // bus_w16(DUMMY_REG,i); + // bus_r16(DUMMY_REG); +/* dum=(((u_int16_t*)(now_ptr))+i); */ +/* *dum=bus_r16(FIFO_DATA_REG); */ +/* a=bus_r16(FIFO_DATA_REG); */ + //dum=(((u_int32_t*)(now_ptr))+i); + + // a=*values;//bus_r(FIFO_DATA_REG); + // if ((adcDisableMask&(3<<(i*2)))==0) { + *((u_int16_t*)now_ptr)=bus_r16(FIFO_DATA_REG);//*values;//bus_r(FIFO_DATA_REG); + + + if (i!=0 || ns!=0) { + a=0; + while (*((u_int16_t*)now_ptr)==*((u_int16_t*)(now_ptr)-1) && a++<10) { + + // printf("******************** %d: fifo %d: new %08x old %08x\n ",ns, i, *((u_int32_t*)now_ptr),*((u_int32_t*)(now_ptr)-1)); + *((u_int16_t*)now_ptr)=bus_r16(FIFO_DATA_REG);//*values; + // printf("%d-",i); + + } + } + now_ptr+=2;//4; + // } +/* while (((adcDisableMask&(3<<((i+1)*2)))>>((i+1)*2))==3) { */ +/* i++; */ +/* } */ + + // if (((adcDisableMask&(3<<((i+1)*2)))>>((i+1)*2))!=3) { + + bus_w16(DUMMY_REG,i+1); + + a = bus_r(LOOK_AT_ME_REG); + //#ifdef VERBOSE + printf("%d %08x\n",i,a); + // } + // *(((u_int16_t*)(now_ptr))+i)=bus_r16(FIFO_DATA_REG); + } + // bus_w16(DUMMY_REG,0); // +/* #ifdef TIMEDBG */ + +/* gettimeofday(&tss,NULL); */ +/* printf("read data loop = %ld usec\n",(tss.tv_usec) - (tse.tv_usec)); */ + +/* #endif */ +//#ifdef VERBOSE + // printf("*"); + //#endif + return ram_values; +} + + + +u_int16_t* fifo_read_frame() +{ +#ifdef TIMEDBG + gettimeofday(&tsss,NULL); +#endif + + // u_int16_t *dum; + int ns=0; + now_ptr=(char*)ram_values; + while(ns>(ipos))&0x1; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibyte>(ipos*4))&0xf; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichan0) { + dynamicRange=16; + nSamples=dr/16; + bus_w(NSAMPLES_REG,nSamples); + } + getDynamicRange(); + allocateRAM(); + printf("Setting dataBytes to %d: dr %d; samples %d\n",dataBytes, dynamicRange, nSamples); + return getDynamicRange(); +} + + + + + + +int getDynamicRange() { + if(myDetectorType == JUNGFRAU){ + dynamicRange=16; + return dynamicRange; + } + + nSamples=bus_r(NSAMPLES_REG); + getChannels(); + dataBytes=nModX*N_CHIP*getChannels()*2; + return dynamicRange*bus_r(NSAMPLES_REG);//nSamples; +} + +int testBus() { + u_int32_t j; + u_int64_t i, n, nt; + // char cmd[100]; + u_int32_t val=0x0; + int ifail=OK; + // printf("%s\n",cmd); + // system(cmd); + i=0; + + n=1000000; + nt=n/100; + printf("testing bus %d times\n",(int)n); + while (i0) + storeInRAM=1; + else + storeInRAM=0; + return allocateRAM(); +} + +int getChannels() { + int nch=32; + int i; + for (i=0; i1) { + + clearRAM(); + ram_values=malloc(size); + // ram_values=realloc(ram_values,size)+2; + // if (ram_values) + // break; + // nSamples--; + //} + + if (ram_values) { + now_ptr=(char*)ram_values; + + //#ifdef VERBOSE + printf("ram allocated 0x%x of size %d to %x\n",(int)now_ptr,(unsigned int) size,(unsigned int)(now_ptr+size)); + //#endif + ram_size=size; + return OK; + } + + + printf("Fatal error: there must be a memory leak somewhere! You can't allocate even one frame!\n"); + return FAIL; + + + + +} + + +int writeADC(int addr, int val) { + + + u_int32_t valw,codata,csmask; + int i,cdx,ddx; + cdx=0; ddx=1; + csmask=0xfc; // 1111100 + + codata=val + (addr<< 8); + printf("***** ADC SPI WRITE TO REGISTER %04X value %04X\n",addr,val); + // start point + valw=0xff; + bus_w16(ADC_WRITE_REG,(valw)); + + //chip sel bar down + valw=((0xffffffff&(~csmask))); + bus_w16(ADC_WRITE_REG,valw); + + for (i=0;i<24;i++) { + //cldwn + valw=valw&(~(0x1<>(23-i))&0x1)<> 8); + // printf("%i: %i %i\n",a, frame[a],v); + avg[a] += ((double)frame[a])/(double)frames; + //if(frame[a] == 8191) + // printf("ch %i: %u\n",a,frame[a]); + } + // printf("********\n"); + numberFrames++; + } + + //no more data or no data + else { + if(getFrames()>-2) { + dataret=FAIL; + printf("no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + + } else { + dataret=FINISHED; + printf("acquisition successfully finished\n"); + + } + printf("dataret %d\n",dataret); + } + } + + + + //double nf = (double)numberFrames; + for(i =0; i < 1280; i++){ + adc = i / 256; + adcCh = (i - adc * 256) / 32; + Ch = i - adc * 256 - adcCh * 32; + adc--; + double v2 = avg[i]; + avg[i] = avg[i]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[i]; + printf("setting avg for channel %i(%i,%i,%i): %i (double= %f (%f))\t", i,adc,adcCh,Ch, v,avg[i],v2); + v=i*100; + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + + /*for(adc = 1; adc < 5; adc++){ + for(adcCh = 0; adcCh < 8; adcCh++){ + for(Ch=0 ; Ch < 32; Ch++){ + int channel = (adc+1) * 32 * 8 + adcCh * 32 + Ch; + double v2 = avg[channel]; + avg[channel] = avg[channel]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[channel]; + printf("setting avg for channel %i: %i (double= %f (%f))\t", channel, v,avg[channel],v2); + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + } + }*/ + + + + printf("frames: %i\n",numberFrames); + printf("corrected avg by: %f\n",(double)numberFrames/(double)frames); + + printf("restoring previous condition\n"); + setFrames(framesBefore); + setPeriod(periodBefore); + + printf("---------------------------\n"); + return 0; +} +uint64_t readPatternWord(int addr) { + uint64_t word=0; + int cntrl=0; + + if (addr>=MAX_PATTERN_LENGTH) + return -1; + + + printf("read %x\n",addr); + cntrl= (addr&APATTERN_MASK) << PATTERN_CTRL_ADDR_OFFSET; + bus_w(PATTERN_CNTRL_REG, cntrl); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl | (1<< PATTERN_CTRL_READ_BIT) ); + usleep(1000); + printf("reading\n"); + word=get64BitReg(PATTERN_OUT_LSB_REG,PATTERN_OUT_MSB_REG); + printf("read %llx\n", word); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl); + printf("done\n"); + + return word; +} + +uint64_t writePatternWord(int addr, uint64_t word) { + + + int cntrl=0; + if (addr>=MAX_PATTERN_LENGTH) + return -1; + + printf("write %x %llx\n",addr, word); + if (word!=-1){ + + set64BitReg(word,PATTERN_IN_REG_LSB,PATTERN_IN_REG_MSB); + + + cntrl= (addr&APATTERN_MASK) << PATTERN_CTRL_ADDR_OFFSET; + bus_w(PATTERN_CNTRL_REG, cntrl); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl | (1<< PATTERN_CTRL_WRITE_BIT) ); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl); + return word; + } else + return readPatternWord(addr); +} +uint64_t writePatternIOControl(uint64_t word) { + if (word!=0xffffffffffffffff) { /*warning: integer constant is too large for ‘long’ type*/ + // printf("%llx %llx %lld",get64BitReg(PATTERN_IOCTRL_REG_LSB,PATTERN_IOCTRL_REG_MSB),word); + set64BitReg(word,PATTERN_IOCTRL_REG_LSB,PATTERN_IOCTRL_REG_MSB); + // printf("************ write IOCTRL (%x)\n",PATTERN_IOCTRL_REG_MSB); + } + return get64BitReg(PATTERN_IOCTRL_REG_LSB,PATTERN_IOCTRL_REG_MSB); + +} +uint64_t writePatternClkControl(uint64_t word) { + if (word!=0xffffffffffffffff) set64BitReg(word,PATTERN_IOCLKCTRL_REG_LSB,PATTERN_IOCLKCTRL_REG_MSB);/*warning: integer constant is too large for ‘long’ type*/ + return get64BitReg(PATTERN_IOCLKCTRL_REG_LSB,PATTERN_IOCLKCTRL_REG_MSB); + +} + +int setPatternLoop(int level, int *start, int *stop, int *n) { + int ret=OK; + int lval=0; + + int nreg; + int areg; + + switch (level ) { + case 0: + nreg=PATTERN_N_LOOP0_REG; + areg=PATTERN_LOOP0_AREG; + break; + case 1: + nreg=PATTERN_N_LOOP1_REG; + areg=PATTERN_LOOP1_AREG; + break; + case 2: + nreg=PATTERN_N_LOOP2_REG; + areg=PATTERN_LOOP2_AREG; + break; + case -1: + nreg=-1; + areg=PATTERN_LIMITS_AREG; + break; + default: + return FAIL; + } + + printf("level %d start %x stop %x nl %d\n",level, *start, *stop, *n); + if (nreg>=0) { + if ((*n)>=0) bus_w(nreg, *n); + printf ("n %d\n",*n); + *n=bus_r(nreg); + printf ("n %d\n",*n); + + } + + printf("level %d start %x stop %x nl %d\n",level, *start, *stop, *n); + lval=bus_r(areg); +/* printf("l=%x\n",bus_r16(areg)); */ +/* printf("m=%x\n",bus_r16_m(areg)); */ + + + + + + printf("lval %x\n",lval); + if (*start==-1) *start=(lval>> ASTART_OFFSET) & APATTERN_MASK; + printf("start %x\n",*start); + + + if (*stop==-1) *stop=(lval>> ASTOP_OFFSET) & APATTERN_MASK; + printf("stop %x\n",*stop); + + lval= ((*start & APATTERN_MASK) << ASTART_OFFSET) | ((*stop & APATTERN_MASK) << ASTOP_OFFSET); + printf("lval %x\n",lval); + + bus_w(areg,lval); + printf("lval %x\n",lval); + + + return ret; +} + + +int setPatternWaitAddress(int level, int addr) { + int reg; + + switch (level) { + case 0: + reg=PATTERN_WAIT0_AREG; + break; + case 1: + reg=PATTERN_WAIT1_AREG; + break; + case 2: + reg=PATTERN_WAIT2_AREG; + break; + default: + return -1; + }; + // printf("BEFORE *********PATTERN IOCTRL IS %llx (%x)\n",writePatternIOControl(-1), PATTERN_IOCTRL_REG_MSB); + + // printf ("%d addr %x (%x)\n",level,addr,reg); + if (addr>=0) bus_w(reg, addr); + // printf ("%d addr %x %x (%x) \n",level,addr, bus_r(reg), reg); + + // printf("AFTER *********PATTERN IOCTRL IS %llx (%x)\n",writePatternIOControl(-1), PATTERN_IOCTRL_REG_MSB); + + return bus_r(reg); +} + + +uint64_t setPatternWaitTime(int level, uint64_t t) { + int reglsb; + int regmsb; + + + switch (level) { + case 0: + reglsb=PATTERN_WAIT0_TIME_REG_LSB; + regmsb=PATTERN_WAIT0_TIME_REG_MSB; + break; + case 1: + reglsb=PATTERN_WAIT1_TIME_REG_LSB; + regmsb=PATTERN_WAIT1_TIME_REG_MSB; + break; + case 2: + reglsb=PATTERN_WAIT2_TIME_REG_LSB; + regmsb=PATTERN_WAIT2_TIME_REG_MSB; + break; + default: + return -1; + } + + + if (t>=0) set64BitReg(t,reglsb,regmsb); + return get64BitReg(reglsb,regmsb); + +} + + +void initDac(int dacnum) { + + + u_int32_t offw,codata; + u_int16_t valw; + int i,ddx,csdx,cdx; + + + + //setting int reference + offw=DAC_REG; + + + ddx=0; cdx=1; + csdx=dacnum/8+2; + + + printf("data bit=%d, clkbit=%d, csbit=%d",ddx,cdx,csdx); + codata=((((0x6)<<4)+((0xf))<<16)+((0x0<<4)&0xfff0)); /*warning: suggest parentheses around + or - inside shift*/ + + valw=0xffff; bus_w(offw,(valw)); // start point + valw=((valw&(~(0x1<>(24-i))&0x1)<>(24-i))&0x1)); + + + valw=((valw&(~(0x1<>16)&0xffff; */ +/* else */ +/* return retval&0xffff; */ + +} + + + + +int setPower(int ind, int val) { + int dacindex=-1; + int dacval=-1; + int pwrindex=-1; + int retval=-1; + int retval1=-1; + + u_int32_t preg; + + int vchip=2700-(getDacRegister(19)*1000)/4095; + int vmax=vchip-200; + int vmin=600; + + printf("---------------------------------------------Current V_Chip is %d mV\n",vchip); + + switch (ind) { + + case V_POWER_CHIP: + dacindex=19; + pwrindex=-1; + break; + case V_POWER_A: + dacindex=22; + pwrindex=1; + break; + case V_POWER_B: + dacindex=21; + pwrindex=2; + break; + case V_POWER_C: + dacindex=20; + pwrindex=3; + break; + case V_POWER_D: + dacindex=18; + pwrindex=4; + break; + case V_POWER_IO: + dacindex=23; + pwrindex=0; + break; + default: + pwrindex=-1; + dacindex=-1; + } + + if (val==-1) { + printf("get\n"); + dacval=-1; + } else { + if (pwrindex>=0) { + printf("vpower\n"); + dacval=((vmax-val)*4095)/(vmax-vmin); + if (dacval<0) + dacval=0; + if (dacval>4095) + dacval=-100; + if (val==-100) + dacval=-100; + + } else { + printf("vchip\n"); + dacval=((2700-val)*4095)/1000; + if (dacval<0) + dacval=0; + if (dacval>4095) + dacval=4095; + } + } + + if (pwrindex>=0 && val!=-1) { + preg=bus_r(POWER_ON_REG); + printf("power reg is %08x\n",bus_r(POWER_ON_REG)); + printf("Switching off power %d\n", pwrindex); + bus_w(POWER_ON_REG,preg&(~(1<<(16+pwrindex)))); + setDac(dacindex,-100); + printf("power reg is %08x\n",bus_r(POWER_ON_REG)); + retval=0; + } + + if (dacindex>0 && dacval!=-100) { + + printf("Setting power %d to %d mV\n",ind,val); + printf("Setting DAC %d to value %d\n",dacindex,dacval); + retval=setDac(dacindex,dacval); + if (pwrindex>=0 && dacval>=0 ) { + preg=bus_r(POWER_ON_REG); + printf("power reg is %08x\n",bus_r(POWER_ON_REG)); + printf("Switching on power %d\n", pwrindex); + bus_w(POWER_ON_REG,preg|((1<<(16+pwrindex)))); + printf("power reg is %08x\n",bus_r(POWER_ON_REG)); + } + } + + if (pwrindex>=0) { + if (bus_r(POWER_ON_REG)&(1<<(16+pwrindex))){ + retval1=vmax-(retval*1900)/4095; + vmax=2700-(getDacRegister(19)*1000)/4095-200; + if (retval1>vmax) + retval1=vmax; + if (retval1=0) + retval1=2700-(retval*1000)/4095; + else + retval1=-1; + } + + /* switch (ind) { */ +/* case V_POWER_A: */ +/* break; */ +/* case V_POWER_B: */ +/* break; */ +/* case V_POWER_C: */ +/* break; */ +/* case V_POWER_D: */ +/* break; */ +/* case V_POWER_IO: */ +/* break; */ +/* case V_POWER_CHIP: */ +/* break; */ +/* default: */ +/* retval1=retval; */ +/* } */ + + + return retval1; + + +} + + + + + + + + + + + + + + + + +int nextDac(){ + + u_int32_t offw,codata; + u_int16_t valw=bus_r(offw); + int i,ddx,csdx,cdx; + + int dacch=0; + + + // printf("**************************************************next dac\n"); + //setting int reference + offw=DAC_REG; + + + ddx=0; cdx=1; + + csdx=2; + + valw=0xffff&(~(0x1<>(24-i)))&0x1); + + valw=(valw&(~(0x1<>(24-i))&0x1)<>(24-i))&0x1)); + + + valw=((valw&(~(0x1<=0) { + + + + // printf("data bit=%d, clkbit=%d, csbit=%d",ddx,cdx,csdx); + + //modified to power down single channels + + // codata=((((0x2)<<4)+((dacch)&0xf))<<16)+((dacvalue<<4)&0xfff0); + codata=(0x3)<>(24-i)))&0x1); + valw=(valw&(~(0x1<>(24-i))&0x1)<>(24-i))&0x1)); + + + valw=((valw&(~(0x1< +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +int mapCSP0(void); + +u_int16_t bus_r16(u_int32_t offset); +u_int16_t bus_w16(u_int32_t offset, u_int16_t data);//aldos function +u_int32_t bus_w(u_int32_t offset, u_int32_t data); +u_int32_t bus_r(u_int32_t offset); + +int setPhaseShiftOnce(); +int phaseStep(int st); +int getPhase(); +int cleanFifo(); +int setDAQRegister(); + +u_int32_t putout(char *s, int modnum); +u_int32_t readin(int modnum); +u_int32_t setClockDivider(int d, int ic); +u_int32_t getClockDivider(int ic); + +void resetPLL(); +u_int32_t setPllReconfigReg(u_int32_t reg, u_int32_t val, int trig); +u_int32_t getPllReconfigReg(u_int32_t reg, int trig); + +u_int32_t setSetLength(int d); +u_int32_t getSetLength(); +u_int32_t setWaitStates(int d); +u_int32_t getWaitStates(); +u_int32_t setTotClockDivider(int d); +u_int32_t getTotClockDivider(); +u_int32_t setTotDutyCycle(int d); +u_int32_t getTotDutyCycle(); +u_int32_t setOversampling(int d); +u_int32_t adcPipeline(int d); + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode); +int getExtSignal(int d); + +u_int32_t setFPGASignal(int d, enum externalSignalFlag mode); +int getFPGASignal(int d); + +int setTiming(int t); + + +int setConfigurationRegister(int d); +int setToT(int d); +int setContinousReadOut(int d); +int startReceiver(int d); + +int setDACRegister(int idac, int val, int imod); +int getDacRegister(int dacnum); + + +int getTemperature(int tempSensor,int imod); +int initHighVoltage(int val,int imod); +int initConfGain(int isettings,int val,int imod); + +int setADC(int adc); +//int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int ival, int udpport); +int configureMAC(uint32_t destip,uint64_t destmac,uint64_t sourcemac,int detipad,int ival,uint32_t destport); +int getAdcConfigured(); + + +u_int64_t getDetectorNumber(); +u_int32_t getFirmwareVersion(); +u_int32_t getFirmwareSVNVersion(); + +int testFifos(void); +u_int32_t testFpga(void); +u_int32_t testRAM(void); +int testBus(void); +int setDigitalTestBit(int ival); + +int64_t set64BitReg(int64_t value, int aLSB, int aMSB); +int64_t get64BitReg(int aLSB, int aMSB); + +int64_t setFrames(int64_t value); +int64_t getFrames(); + +int64_t setExposureTime(int64_t value); +int64_t getExposureTime(); + +int64_t setGates(int64_t value); +int64_t getGates(); + +int64_t setDelay(int64_t value); +int64_t getDelay(); + +int64_t setPeriod(int64_t value); +int64_t getPeriod(); + +int64_t setTrains(int64_t value); +int64_t getTrains(); + +int64_t setProbes(int64_t value); +int64_t getProbes(); + +int64_t getProgress(); +int64_t setProgress(); + +int64_t getActualTime(); +int64_t getMeasurementTime(); +int64_t getFramesFromStart(); + +u_int32_t runBusy(void); +u_int32_t runState(void); +u_int32_t dataPresent(void); + + +int startStateMachine(); +int stopStateMachine(); +int startReadOut(); +u_int32_t fifoReset(void); +u_int32_t fifoReadCounter(int fifonum); +u_int32_t fifoReadStatus(); + + +u_int32_t fifo_full(void); + + + +u_int16_t* fifo_read_event(int ns); +u_int16_t* fifo_read_frame(); +u_int32_t* decode_data(int* datain); +//u_int32_t move_data(u_int64_t* datain, u_int64_t* dataout); +int setDynamicRange(int dr); +int getDynamicRange(); +int getNModBoard(); +int setNMod(int n); +int getNMod(); + +int setStoreInRAM(int b); +int allocateRAM(); + + +int writeADC(int addr, int val); +int prepareADC(); + + +int clearRAM(); + + +int setMaster(int f); +int setSynchronization(int s); + +int loadImage(int index, short int ImageVals[]); +int readCounterBlock(int startACQ, short int CounterVals[]); +int resetCounterBlock(int startACQ); + +int calibratePedestal(int frames); + +uint64_t writePatternWord(int addr, uint64_t word); +uint64_t writePatternIOControl(uint64_t word); +uint64_t writePatternClkControl(uint64_t word); +int setPatternLoop(int level, int *start, int *stop, int *n); +int setPatternWaitAddress(int level, int addr); +uint64_t setPatternWaitTime(int level, uint64_t t); + + +void initDac(int dacnum); +int setDac(int dacnum,int dacvalue); + +int setPower(int ind, int val); + +ROI *setROI(int nroi,ROI* arg,int *retvalsize, int *ret); +int getChannels(); + +/* + +u_int32_t setNBits(u_int32_t); +u_int32_t getNBits(); +*/ + +/* +//move to mcb_funcs? + +int readOutChan(int *val); +u_int32_t getModuleNumber(int modnum); +int testShiftIn(int imod); +int testShiftOut(int imod); +int testShiftStSel(int imod); +int testDataInOut(int num, int imod); +int testExtPulse(int imod); +int testExtPulseMux(int imod, int ow); +int testDataInOutMux(int imod, int ow, int num); +int testOutMux(int imod); +int testFpgaMux(int imod); +int calibration_sensor(int num, int *values, int *dacs) ; +int calibration_chip(int num, int *values, int *dacs); +*/ + + +#endif diff --git a/slsDetectorSoftware/jctbDetectorServer/gitInfoMoench.h b/slsDetectorSoftware/jctbDetectorServer/gitInfoMoench.h new file mode 100644 index 000000000..270653967 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/gitInfoMoench.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "git@gitorious.psi.ch:sls_det_software/sls_detector_software.git/moenchDetectorServer" +//#define SVNREPPATH "" +#define SVNREPUUID "046a469b1e6582c4c55bd6eaeb4818b618d0a9a9" +//#define SVNREV 0x14 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "Maliakal_Dhanya" +#define SVNREV 0x14 +#define SVNDATE 0x20140603 +// diff --git a/slsDetectorSoftware/jctbDetectorServer/gitInfoMoenchTmp.h b/slsDetectorSoftware/jctbDetectorServer/gitInfoMoenchTmp.h new file mode 100644 index 000000000..58e48f497 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/gitInfoMoenchTmp.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "" +//#define SVNREPPATH "" +#define SVNREPUUID "" +//#define SVNREV "" +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "" +#define SVNREV "" +#define SVNDATE "" +// diff --git a/slsDetectorSoftware/jctbDetectorServer/jungfrauDetectorServerTest b/slsDetectorSoftware/jctbDetectorServer/jungfrauDetectorServerTest new file mode 100755 index 000000000..25804a0ba Binary files /dev/null and b/slsDetectorSoftware/jctbDetectorServer/jungfrauDetectorServerTest differ diff --git a/slsDetectorSoftware/jctbDetectorServer/mcb_funcs.c b/slsDetectorSoftware/jctbDetectorServer/mcb_funcs.c new file mode 100755 index 000000000..edf99652a --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/mcb_funcs.c @@ -0,0 +1,2701 @@ +#ifdef MCB_FUNCS + +#include +#include +#include +#include +#include +#include "registers_m.h" + +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" + + +/* global variables */ +#undef DEBUG +#undef DEBUGOUT + +extern int nModX; +//extern int dataBytes; +extern int dynamicRange; +enum detectorSettings thisSettings; + +int sChan, sChip, sMod, sDac, sAdc; +const int allSelected=-2; +const int noneSelected=-1; + + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +int *detectorDacs=NULL; +int *detectorAdcs=NULL; +//int numberOfProbes; + +ROI rois[MAX_ROIS]; +int nROI=0; +extern enum detectorType myDetectorType; + +/** for jungfrau reinitializing macro later in server_funcs.c in initDetector*/ +extern int N_CHAN; +extern int N_CHIP; +extern int N_DAC; +extern int N_ADC; +extern int N_CHANS; + +extern int nChans; +extern int nChips; +extern int nDacs; +extern int nAdcs; + +int initDetector() { + + int imod; + // sls_detector_module *myModule; + int n=getNModBoard(); + nModX=n; + +#ifdef VERBOSE + printf("Board is for %d modules\n",n); +#endif + + if(myDetectorType == JUNGFRAU){ + N_CHAN=JUNGFRAU_NCHAN; + N_CHIP=JUNGFRAU_NCHIP; + N_DAC=JUNGFRAU_NDAC; + N_ADC=JUNGFRAU_NADC; + N_CHANS=JUNGFRAU_NCHANS; + + nChans=N_CHAN; + nChips=N_CHIP; + nDacs=N_DAC; + nAdcs=N_ADC; + } + + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorDacs=malloc(n*N_DAC*sizeof(int)); + detectorAdcs=malloc(n*N_ADC*sizeof(int)); + detectorChips=NULL; + detectorChans=NULL; + detectorAdcs=NULL; + if(myDetectorType != JUNGFRAU){ + detectorChips=malloc(n*N_CHIP*sizeof(int)); + detectorChans=malloc(n*N_CHIP*N_CHAN*sizeof(int)); + } + +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",(unsigned int)(detectorModules), (unsigned int)(detectorModules+n)); + printf("dacs from 0x%x to 0x%x\n",(unsigned int)(detectorDacs), (unsigned int)(detectorDacs+n*N_DAC)); + printf("adcs from 0x%x to 0x%x\n",(unsigned int)(detectorAdcs), (unsigned int)(detectorAdcs+n*N_ADC)); + if(myDetectorType != JUNGFRAU){ + printf("chips from 0x%x to 0x%x\n",(unsigned int)(detectorChips), (unsigned int)(detectorChips+n*N_CHIP)); + printf("chans from 0x%x to 0x%x\n",(unsigned int)(detectorChans), (unsigned int)(detectorChans+n*N_CHIP*N_CHAN)); + } +#endif + + + for (imod=0; imoddacs=detectorDacs+imod*N_DAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*N_ADC; + if(myDetectorType != JUNGFRAU){ + (detectorModules+imod)->chipregs=detectorChips+imod*N_CHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*N_CHIP*N_CHAN; + } + (detectorModules+imod)->ndac=N_DAC; + (detectorModules+imod)->nadc=N_ADC; + (detectorModules+imod)->nchip=N_CHIP; + (detectorModules+imod)->nchan=N_CHIP*N_CHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + + /* + setCSregister(ALLMOD); //commented out by dhanya + setSSregister(ALLMOD); + counterClear(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + */ + + /* initialize dynamic range etc. */ + /* dynamicRange=getDynamicRange(); //always 16 not required commented out + nModX=setNMod(-1);*/ + + // dynamicRange=32; + // initChip(0, 0,ALLMOD); + //nModX=n; + // + allocateRAM(); + + return OK; +} + + + + +int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) { + destChan->chan=srcChan->chan; + destChan->chip=srcChan->chip; + destChan->module=srcChan->module; + destChan->reg=srcChan->reg; + return OK; +} + + +int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip) { + + int ichan; + int ret=OK; + if ((srcChip->nchan)>(destChip->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + + destChip->nchan=srcChip->nchan; + destChip->reg=srcChip->reg; + destChip->chip=srcChip->chip; + destChip->module=srcChip->module; + for (ichan=0; ichan<(srcChip->nchan); ichan++) { + *((destChip->chanregs)+ichan)=*((srcChip->chanregs)+ichan); + } + return ret; +} + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { + + int ichip, idac, ichan, iadc; + + int ret=OK; + +#ifdef VERBOSE + printf("Copying module %x to module %x\n",(unsigned int)(srcMod),(unsigned int)(destMod)); +#endif + + if (srcMod->module>=0) { +#ifdef VERBOSE + printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); +#endif + destMod->module=srcMod->module; + } + if (srcMod->serialnumber>=0){ +/* #ifdef VERBOSE */ +/* printf("Copying module serial number %x to module serial number %x\n",srcMod->serialnumber,destMod->serialnumber); */ +/* #endif */ + destMod->serialnumber=srcMod->serialnumber; + } + if ((srcMod->nchip)>(destMod->nchip)) { + printf("Number of chip of source is larger than number of chips of destination\n"); + return FAIL; + } + if ((srcMod->nchan)>(destMod->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + if ((srcMod->ndac)>(destMod->ndac)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + if ((srcMod->nadc)>(destMod->nadc)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + +#ifdef VERBOSE + printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); + printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); + printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); + printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); + +#endif + + + + destMod->ndac=srcMod->ndac; + destMod->nadc=srcMod->nadc; + destMod->nchip=srcMod->nchip; + destMod->nchan=srcMod->nchan; + if (srcMod->reg>=0) + destMod->reg=srcMod->reg; +#ifdef VERBOSE + printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); +#endif + if (srcMod->gain>=0) + destMod->gain=srcMod->gain; + if (srcMod->offset>=0) + destMod->offset=srcMod->offset; + + // printf("copying gain and offset %f %f to %f %f\n",srcMod->gain,srcMod->offset,destMod->gain,destMod->offset); + + if(myDetectorType != JUNGFRAU){ + for (ichip=0; ichip<(srcMod->nchip); ichip++) { + if (*((srcMod->chipregs)+ichip)>=0) + *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); + } + for (ichan=0; ichan<(srcMod->nchan); ichan++) { + if (*((srcMod->chanregs)+ichan)>=0) + *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); + } + } + + for (idac=0; idac<(srcMod->ndac); idac++) { + if (*((srcMod->dacs)+idac)>=0) + *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } + + for (iadc=0; iadc<(srcMod->nadc); iadc++) { + if (*((srcMod->adcs)+iadc)>=0) + *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); + } + + return ret; +} + + + +/* Register commands */ + + +/* int clearDACSregister(int imod) { */ + +/* putout("1111111111111111",imod);//reset */ +/* putout("1111111111111110",imod);//cs down */ + +/* /\* commented out by dhanya */ +/* putout("0000000001000000",imod); */ +/* putout("0000000101000000",imod); */ +/* putout("0000000101000000",imod); */ +/* putout("0000000001000000",imod); */ +/* *\/ */ +/* #ifdef DEBUG */ +/* fprintf(stdout, "Clearing DAC shiftregister\n"); */ +/* #endif */ +/* // sDac=0; */ +/* sMod=imod; */ +/* if (imod==ALLMOD) */ +/* sMod=allSelected; */ +/* return OK; */ +/* } */ + +/* int nextDAC(int imod) { */ + +/* putout("1111111111111011",imod);//cs up */ +/* putout("1111111111111001",imod);//clk down */ +/* putout("1111111111111111",imod);//reset */ + +/* /\*commented out by dhanya */ +/* putout("0000000001000000",imod); */ +/* putout("0000000001001000",imod); */ +/* putout("0000000001000000",imod); */ +/* *\/ */ +/* #ifdef DEBUG */ +/* fprintf(stdout, "Next DAC\n"); */ +/* #endif */ +/* // sDac++; */ +/* sMod=imod; */ +/* if (imod==ALLMOD) */ +/* sMod=allSelected; */ +/* return OK; */ +/* } */ + + +int clearCSregister(int imod) { + + putout("0000000001000000",imod); + putout("0000100001000000",imod); + putout("0000100001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Clearing CS shiftregister\n"); +#endif + /* + sChan=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + */ + sChip=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + //putout("0000000000000000",imod); + return 0; +} + +int setCSregister(int imod){ + + putout("0000000001000000",imod); + putout("0001000001000000",imod); + putout("0001000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Setting CS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChip=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextChip(int imod){ + + putout("0000000001000000",imod); + putout("0010000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Next Chip\n"); +#endif + sChip++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int firstChip(int imod){ + + putout("0100000001000000",imod); + putout("0110000001000000",imod); + putout("0100000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "First Chip\n"); +#endif + sChip=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int clearSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0000111000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Clearing SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int setSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0001011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Setting SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextStrip(int imod){ + putout("0000011000000000",imod); + putout("0010011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"|-"); +#endif + sChan++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int selChannel(const int strip,int imod) { + int istrip; + clearSSregister(imod); + nextStrip(imod); + for (istrip=0; istrip=0 && imod=0) */ +/* initDAC(ind,val, imod); */ + +/* if (imod>=0 && imodgain,(detectorModules+imod)->offset); */ +/* #endif */ +/* if ((detectorModules+imod)->gain>0) */ +/* myg=(detectorModules+imod)->gain; */ +/* else { */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myg=g[thisSettings]; */ +/* // else */ +/* //myg=-1; */ +/* } */ + +/* if ((detectorModules+imod)->offset>0) */ +/* myo=(detectorModules+imod)->offset; */ +/* else { */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myo=o[thisSettings]; */ +/* // else */ +/* //myo=-1; */ +/* } */ + +/* if (myg>0 && myo>0) { */ +/* //ethr=(myo-detectorDacs[VTHRESH+imod*N_DAC])*1000/myg; */ + +/* ethr=(myo-setDACRegister(VDAC0,-1,imod))*1000/myg;//edited by dhanya */ +/* // else */ +/* // ethr=-1; */ + +/* } */ +/* #ifdef VERBOSE */ +/* //printf("module=%d gain=%f, offset=%f, dacu=%f\n",imod, myg, myo, detectorDacs[VTHRESH+imod*N_DAC]); */ +/* printf("module=%d gain=%f, offset=%f, dacu=%d\n",imod, myg, myo,(int)(setDACRegister(VDAC0,-1,imod)));//edited by dhanya */ +/* printf("Threshold energy of module %d is %d eV\n", imod, ethr); */ +/* #endif */ + +/* if (imod==0) */ +/* ret=ethr; */ +/* else { */ +/* if (ethr>(ret+100) || ethr<(ret-100)) */ +/* return FAIL; */ +/* } */ +/* } */ +/* } */ +/* return ret; */ +/* } */ + +/* int setThresholdEnergy(int ethr) { */ +/* double g[3]=DEFAULTGAIN; */ +/* double o[3]=DEFAULTOFFSET; */ +/* double myg=-1, myo=-1; */ +/* int dacu; */ +/* int imod; */ +/* int ret=ethr; */ + +/* setSettings(GET_SETTINGS,-1);//-1 added by dhanya */ +/* if (thisSettings>=0 || thisSettings<3){ */ +/* myg=g[thisSettings]; */ +/* myo=o[thisSettings]; */ +/* } */ +/* for (imod=0; imodgain>0) */ +/* myg=(detectorModules+imod)->gain; */ +/* else */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myg=g[thisSettings]; */ +/* else */ +/* myg=-1; */ +/* if ((detectorModules+imod)->offset>0) */ +/* myo=(detectorModules+imod)->offset; */ +/* else */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myo=o[thisSettings]; */ +/* else */ +/* myo=-1; */ +/* } else { */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myo=o[thisSettings]; */ +/* else */ +/* myo=-1; */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myg=g[thisSettings]; */ +/* else */ +/* myg=-1; */ +/* } */ +/* if (myg>0 && myo>0) { */ +/* dacu=myo-myg*((double)ethr)/1000.; */ +/* #ifdef VERBOSE */ +/* printf("module %d (%x): gain %f, off %f, energy %d eV, dac %d\n",imod,(unsigned int)((detectorModules+imod)),(detectorModules+imod)->gain,(detectorModules+imod)->offset, ethr,dacu); */ +/* #endif */ +/* } else { */ +/* dacu=ethr; */ +/* #ifdef VERBOSE */ +/* printf("could not set threshold energy for module %d, settings %d (offset is %f; gain is %f)\n",imod,thisSettings,myo,myg); */ +/* #endif */ +/* } */ +/* initDACbyIndexDACU(VDAC0, dacu, imod); ///needs to be fixed dhanya */ +/* } */ +/* return ret; */ +/* } */ + + + +/* int getDACbyIndexDACU(int ind, int imod) { */ +/* /\* */ +/* if (detectorDacs) { */ +/* if (imodndac) */ +/* return (detectorDacs[ind+imod*N_DAC]); */ +/* } */ +/* return FAIL; */ +/* *\/ */ +/* return setDACRegister(ind, -1, imod); */ +/* } */ + + +/* int initDAC(int dac_addr, int value, int imod) { */ +/* // int i; */ +/* #ifdef VERBOSE */ +/* printf("Programming dac %d with value %d\n", dac_addr, value); */ +/* #endif */ +/* clearDACSregister(imod); */ +/* program_one_dac(dac_addr,value,imod); */ +/* nextDAC(imod); */ +/* clearDACSregister(imod); */ + +/* return 0; */ +/* } */ + +int getTemperatureByModule(int tempSensor, int imod) +{ + int im; + //for the particular module + if (imod>=0 && imod=0 && imod=0 && imod=0) { */ +/* #ifdef VERBOSE */ +/* fprintf(stdout, "voltage %d\n", *(v+iaddr)); */ +/* #endif */ +/* program_one_dac(iaddr, *(v+iaddr),imod); */ +/* } */ +/* nextDAC(imod); */ +/* } */ + + +/* clearDACSregister(imod); */ + +/* return 0; */ + +/* } */ + + + + +int setSettings(int i, int imod) { +#ifdef VERBOSE + if(i==-1) + printf("\nReading settings of detector...\n"); + else + printf("\ninside set settings wit settings=%d...\n",i); +#endif + int isett=-1,val=-1,retval=-1; + enum conf_gain { + dynamic = 0x0f00, //dynamic + dynamichighgain0 = 0x0f01, //dynamichighgain0 + fixgain1 = 0x0f02, //fixgain1 + fixgain2 = 0x0f06, //fixgain2 + forceswitchgain1 = 0x1f00, //forceswitchgain1 + forceswitchgain2 = 0x3f00 //forceswitchgain2 + }; + + //determine conf value to write + if(i!=GET_SETTINGS){ + switch(i){ + case DYNAMICGAIN: val = dynamic;break; + case DYNAMICHG0: val = dynamichighgain0;break; + case FIXGAIN1: val = fixgain1;break; + case FIXGAIN2: val = fixgain2;break; + case FORCESWITCHG1: val = forceswitchgain1;break; + case FORCESWITCHG2: val = forceswitchgain2;break; + default: + printf("Error: This settings is not defined for this detector %d\n",i); + return GET_SETTINGS; + } + } + + retval=initConfGainByModule(i,val,imod); + + switch(retval){ + case dynamic: isett=DYNAMICGAIN; break; + case dynamichighgain0: isett=DYNAMICHG0; break; + case fixgain1: isett=FIXGAIN1; break; + case fixgain2: isett=FIXGAIN2; break; + case forceswitchgain1: isett=FORCESWITCHG1; break; + case forceswitchgain2: isett=FORCESWITCHG2; break; + default: + isett=UNDEFINED; + printf("Error:Wrong settings read out from Gain Reg 0x%x\n",retval); + break; + } + + thisSettings=isett; +//#ifdef VERBOSE + printf("detector settings are %d\n",thisSettings); +//#endif + return thisSettings; +} + + + + +/* Initialization*/ + +int initChannelbyNumber(sls_detector_channel myChan) {printf("in init channel by number\n"); + int reg=myChan.reg; + int ft=reg & TRIM_DR; + int cae=(reg>>(NTRIMBITS))&1; + int ae=(reg>>(NTRIMBITS+1))&1; + int coe=(reg>>(NTRIMBITS+2))&1; + int ocoe=(reg>>(NTRIMBITS+3))&1; + int counts=(reg>>(NTRIMBITS+4)); +#ifdef VERBOSE + printf("Initializing channel %d chip %d module %d reg %x\n",myChan.chan,myChan.chip,myChan.module, reg); + printf("trim %d, cae %d, ae %d, coe %d, ocoe %d, counts %d\n",ft, cae, ae, coe, ocoe, counts); +#endif + + if (myChan.chip<0) + setCSregister(myChan.module); + else + selChip(myChan.chip,myChan.module); + + if (myChan.chan<0) + setSSregister(myChan.module); + else + selChannel(myChan.chan,myChan.module); + + initChannel(ft,cae,ae, coe, ocoe, counts,myChan.module); + + setDynamicRange(dynamicRange); + + setCSregister(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + + return myChan.reg; + +} + +int getChannelbyNumber(sls_detector_channel* myChan) { + int imod, ichip, ichan; + imod=myChan->module; + ichip=myChan->chip; + ichan=myChan->chan; + + if (detectorChans) { + if (imod=0) { + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + myChan->reg=detectorChans[imod*N_CHAN*N_CHIP+ichip*N_CHAN+ichan]; + return OK; + } + } + return FAIL; + +} + +int getTrimbit(int imod, int ichip, int ichan) { + if (detectorChans) { + if (imod=0) + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + return (detectorChans[imod*N_CHAN*N_CHIP+ichip*N_CHAN+ichan] & TRIM_DR); + } + + return -1; +} + +int initChannel(int ft,int cae, int ae, int coe, int ocoe, int counts, int imod){ + + int ibit, bit, i, im, ichip, ichan; + int chanmi, chanma, chipmi, chipma, modmi, modma; + + + + sMod=imod; + // printf("initializing module %d\n",sMod); + if (imod==ALLMOD) { + sMod=allSelected; + + // printf("initializing all modules\n"); + } + + if (sChan==allSelected) { + // printf("initializing all channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=N_CHAN; + } else if (sChan==noneSelected || sChan>N_CHAN || sChan<0) { + // printf("initializing no channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=-1; + } else { + // printf("initializing channel %d ft=%d coe=%d\n",sChan, ft,coe); + chanmi=sChan; + chanma=sChan+1; + } + + if (sChip==allSelected) { + // printf("initializing all chips\n"); + chipmi=0; + chipma=N_CHIP; + } else if (sChip==noneSelected || sChip>N_CHIP || sChip<0) { + // printf("initializing no chips\n"); + chipmi=0; + chipma=-1; + } else { + // printf("initializing chip %d\n",sChip); + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + return 1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChans) { + for (im=modmi; im63 || ft<0) { + fprintf(stdout,"Fine Threshold is %d while should be between 0 and 63!",ft); + return 1; + } + /*cal_enable*/ + if (cae) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + } + /*n_an_enable*/ + if (ae) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } else { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } + /*trb5*/ + ibit=5; + bit=ft & (1<>1; + int nchan, ichan; + int ft, cae, ae, coe, ocoe, counts, chanreg; + + + + nchan=myChip.nchan; + if (ichip<0) + setCSregister(imod); + else + selChip(ichip,imod); + + clearSSregister(imod); + for (ichan=0; ichan>(NTRIMBITS+1))&1; + ae=(chanreg>>(NTRIMBITS+2))&1; + coe=((chanreg)>>(NTRIMBITS+3))&1; + ocoe=((chanreg)>>(NTRIMBITS+4))&1; + counts=((chanreg)>>(NTRIMBITS+5)); + nextStrip(imod); + initChannel(ft,cae,ae, coe, ocoe, counts,imod); + } + initChip(obe,ow,imod); + return myChip.reg; + +} + +int getChipbyNumber(sls_detector_chip* myChip){ + int imod, ichip; + imod=myChip->module; + ichip=myChip->chip; + + if (detectorChips) { + if (imodnchip) { + myChip->reg=detectorChips[ichip+imod*N_CHIP]; + myChip->nchan=N_CHAN; + myChip->chanregs=detectorChans+imod*N_CHAN*N_CHIP+ichip*N_CHIP; + return OK; + } + } + return FAIL; + +} + + + +int initChip(int obe, int ow,int imod){ + int i; + int im, ichip; + int chipmi, chipma, modmi, modma; + /* switch (ow) { + case 0:; + case 1: + setDynamicRange(32); + break; + case 2: + setDynamicRange(16); + break; + case 3: + setDynamicRange(8); + break; + case 4: + setDynamicRange(4); + break; + case 5: + setDynamicRange(1); + break; + default: + setDynamicRange(32); + break; + } + */ + +#ifdef DEBUGOUT + printf("Initializing chip\n"); +#endif + putout("0000000000000000",imod); +#ifdef DEBUGOUT + printf("Output mode= %d\n", ow); +#endif + + /* clearing shift in register */ + for (i=0; i<10; i++) + putout("0000100000000000",imod); + putout("0000000000000000",imod); + + if (ow>0) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + for (i=0; i<(OUTMUX_OFFSET-1); i++) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>1) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>2) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>3) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>4) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + } +#ifdef DEBUGOUT + printf("Output buffer enable= %d\n", obe); +#endif + if (obe) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + /*}*/ + putout("0000000000000000",imod); + + + + + + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + + + if (sChip==allSelected) { + chipmi=0; + chipma=N_CHIP; + } else if (sChip==noneSelected || sChip>N_CHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imN_CHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imnModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorModules) { + for (im=modmi; imreg)=cm; +#ifdef VERBOSE + printf("imod=%d reg=%d (%x)\n",im,(detectorModules+im)->reg,(unsigned int)((detectorModules+im))); +#endif + } + } + return 0; +} + +int initModulebyNumber(sls_detector_module myMod) { + + printf("\ninside initmoduleynumberrrr..\n"); + printf("000\n"); + int nchip,nchan;//int ichip, nchip, ichan, nchan; + int im, modmi,modma; + // int ft, cae, ae, coe, ocoe, counts, chanreg; + int imod; + // int obe; + // int ow; + /* int v[N_DAC];*/ + int retval =-1, idac; + + + nchip=myMod.nchip; + nchan=(myMod.nchan)/nchip; + + imod=myMod.module; + sMod=imod; + + if (sMod==ALLMOD) + sMod=allSelected; + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {// (sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + printf("222\n"); + /* + for (idac=0; idacmodule; +#ifdef VERBOSE + printf("Getting module %d\n",imod); +#endif + if (detectorModules) { + copyModule(myMod,detectorModules+imod); + ; + } else + return FAIL; + + return OK; +} + +/* To chips */ +int clearCounter(int imod){ + int i; +#ifdef DEBUG + printf("Clearing counter with contclear\n"); +#endif + putout("0000000000000000",imod); + for (i=0; i<10; i++) + putout("0000000000010000",imod); + putout("0000000000000000",imod); + + return 0; +} + +int clearOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Clearing output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0000110000000000",imod); + putout("0000010000000000",imod); + return 0; +} +int setOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Setting output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0001010000000000",imod); + putout("0000010000000000",imod); + return 0; +} + + +int extPulse(int ncal, int imod) { + int ical; +#ifdef DEBUG + printf("Giving a clock pulse to the counter\n"); +#endif + for (ical=0; ical0 && i%2==0) { + printf("Shift in: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<0 && (dum & (1<0) { + printf("Shift out: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, (dum &1<0 && i%2==0) { + printf("Shift stsel: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<> 1; + + + putout("0000000000000000",ALLMOD); + putout("0010000000000000",ALLMOD); //change mux setting + putout("0000000000000000",ALLMOD); + } + + printf("Test FpgaMux module %d : %d errors\n", imod,result); + if (result) + return 1; + else + return 0; +} + + + + + + + + + +int calibration_sensor(int num, int *v, int *dacs) { + int ich, ichip, imod; + int val[10]; + + + printf("calibrating sensor..."); + for (imod=0; imod=0){ */ + +/* //clear rois */ +/* for(i=0;i=0) && (adc<=4)); */ +/* else { */ +/* printf("warning:adc value greater than 5. deleting roi\n"); */ +/* adc=-1; */ +/* } */ +/* } */ +/* } */ + + +/* //set rois for just 1 adc - take only 1st roi */ +/* if(adc!=-1){ */ +/* rois[0].xmin=adc*(GOTTHARDNCHAN*NCHIPS_PER_ADC); */ +/* rois[0].xmax=(adc+1)*(GOTTHARDNCHAN*NCHIPS_PER_ADC)-1; */ +/* rois[0].ymin=-1; */ +/* rois[0].ymax=-1; */ +/* nROI = 1; */ +/* }else */ +/* nROI = 0; */ + +/* if((arg[0].xmin!=rois[0].xmin)||(arg[0].xmax!=rois[0].xmax)||(arg[0].ymin!=rois[0].ymin)||(arg[0].ymax!=rois[0].ymax)) */ +/* *ret=FAIL; */ +/* if(n!=nROI) */ +/* *ret=FAIL; */ + +/* //set adc of interest */ +/* setADC(adc); */ +/* } */ + +/* //#ifdef VERBOSE */ +/* printf("Rois:\n"); */ +/* for( i=0;i +#include "communication_funcs.h" +#include "server_funcs.h" +#include + + + +extern int sockfd; +extern int phase_shift; + + + +void error(char *msg) +{ + perror(msg); +} + +int main(int argc, char *argv[]) +{ + int portno, b; + char cmd[500]; + int retval=OK; + int sd, fd; + int iarg; + int checkType = 1; + + + for(iarg=1; iarg 2) && (!strcasecmp(argv[2],"stopserver"))){ + portno = DEFAULT_PORTNO+1; + if ( sscanf(argv[1],"%d",&portno) ==0) { + printf("could not open stop server: unknown port\n"); + return 1; + } + b=0; + printf("\n\nStop Server\nOpening stop server on port %d\n",portno); + checkType=0; + + } + + //control server + else { + portno = DEFAULT_PORTNO; + if(checkType) + sprintf(cmd,"%s %d stopserver &",argv[0],DEFAULT_PORTNO+1); + else + sprintf(cmd,"%s %d stopserver -test with_gotthard &",argv[0],DEFAULT_PORTNO+1); + printf("\n\nControl Server\nOpening control server on port %d\n",portno ); + + //printf("\n\ncmd:%s\n",cmd); + system(cmd); + b=1; + checkType=1; + + } + + + + + + init_detector(b, checkType); + + + sd=bindSocket(portno); + sockfd=sd; + if (getServerError(sd)) { + printf("server error!\n"); + return -1; + } + + /* assign function table */ + function_table(); +#ifdef VERBOSE + printf("function table assigned \n"); +#endif + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Waiting for client call\n"); +#endif + fd=acceptConnection(sockfd); +#ifdef VERY_VERBOSE + printf("Conenction accepted\n"); +#endif + retval=decode_function(fd); +#ifdef VERY_VERBOSE + printf("function executed\n"); +#endif + closeConnection(fd); +#ifdef VERY_VERBOSE + printf("connection closed\n"); +#endif + } + + exitServer(sockfd); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/jctbDetectorServer/server_defs.h b/slsDetectorSoftware/jctbDetectorServer/server_defs.h new file mode 100755 index 000000000..781cefc33 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/server_defs.h @@ -0,0 +1,78 @@ +#ifndef SERVER_DEFS_H +#define SERVER_DEFS_H + +#include "sls_detector_defs.h" + +#include + + +// Hardware definitions +#define NMAXMODY 1 +#define NMAXMOD (NMAXMODX*NMAXMODY) + +#define NCHAN 32 +#define NCHIP 1 +#define NADC 1 + +#ifdef CTB +#define NDAC 24 +#define NPWR 5 +#else +#define NDAC 16 +#define NPWR 0 +#endif +#define DAC_CMD_OFF 20 + +#define NMAXMODX 1 +#define NCHANS (NCHAN*NCHIP*NMAXMOD) +#define NDACS (NDAC*NMAXMOD) + +#define JUNGFRAU_NCHAN (256*256) +#define JUNGFRAU_NCHIP 8 +#define JUNGFRAU_NADC 0 +#define JUNGFRAU_NDAC 16 +#define JUNGFRAU_NCHANS (JUNGFRAU_NCHAN*JUNGFRAU_NCHIP*NMAXMOD) + + + +/**when moench readout tested with gotthard module*/ +#define GOTTHARDNCHAN 128 +#define GOTTHARDNCHIP 10 + + +#define NTRIMBITS 6 +#define NCOUNTBITS 24 + +#define NCHIPS_PER_ADC 2 + +//#define TRIM_DR ((2**NTRIMBITS)-1) +//#define COUNT_DR ((2**NCOUNTBITS)-1) +#define TRIM_DR (((int)pow(2,NTRIMBITS))-1) +#define COUNT_DR (((int)pow(2,NCOUNTBITS))-1) + + +#define ALLMOD 0xffff +#define ALLFIFO 0xffff + +#define GOTTHARD_ADCSYNC_VAL 0x32214 +#define ADCSYNC_VAL 0x02111 +#define TOKEN_RESTART_DELAY 0x88000000 +#define TOKEN_RESTART_DELAY_ROI 0x1b000000 +#define TOKEN_TIMING_REV1 0x1f16 +#define TOKEN_TIMING_REV2 0x1f0f + +#define DEFAULT_PHASE_SHIFT 0 // 120 +#define DEFAULT_IP_PACKETSIZE 0x0522 +#define DEFAULT_UDP_PACKETSIZE 0x050E +#define ADC1_IP_PACKETSIZE 256*2+14+20 +#define ADC1_UDP_PACKETSIZE 256*2+4+8+2 + +#ifdef VIRTUAL +#define DEBUGOUT +#endif + +#define CLK_FREQ 156.25E+6 +#define ADC_CLK_FREQ 32E+6 + + +#endif diff --git a/slsDetectorSoftware/jctbDetectorServer/server_funcs.c b/slsDetectorSoftware/jctbDetectorServer/server_funcs.c new file mode 100755 index 000000000..e4551b3cb --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/server_funcs.c @@ -0,0 +1,3513 @@ +#include "sls_detector_defs.h" +#include "sls_receiver_defs.h" +#include "server_funcs.h" +#include "server_defs.h" +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers_m.h" +#include "gitInfoMoench.h" + +#define FIFO_DATA_REG_OFF 0x50<<11 +// Global variables + + +int (*flist[256])(int); + + +//defined in the detector specific file +/* #ifdef MYTHEND */ +/* const enum detectorType myDetectorType=MYTHEN; */ +/* #elif GOTTHARDD */ +/* const enum detectorType myDetectorType=GOTTHARD; */ +/* #elif EIGERD */ +/* const enum detectorType myDetectorType=EIGER; */ +/* #elif PICASSOD */ +/* const enum detectorType myDetectorType=PICASSO; */ +/* #elif MOENCHD */ +/* const enum detectorType myDetectorType=MOENCH; */ +/* #else */ +enum detectorType myDetectorType=GENERIC; +/* #endif */ + + +extern int nModX; +extern int nModY; +extern int dataBytes; +extern int nSamples; +extern int dynamicRange; +extern int storeInRAM; + +extern int lockStatus; +extern char lastClientIP[INET_ADDRSTRLEN]; +extern char thisClientIP[INET_ADDRSTRLEN]; +extern int differentClients; + +/* global variables for optimized readout */ +extern unsigned int *ram_values; +char *dataretval=NULL; +int nframes, iframes, dataret; +char mess[1000]; + +int digitalTestBit = 0; + +extern int withGotthard; + + +int adcvpp=0x4; + +/** for jungfrau reinitializing macro later */ +int N_CHAN=NCHAN; +int N_CHIP=NCHIP; +int N_DAC=NDAC; +int N_ADC=NADC; +int N_CHANS=NCHANS; + + +int init_detector(int b, int checkType) { + + int i; + if (mapCSP0()==FAIL) { printf("Could not map memory\n"); + exit(1); + } + + //print version + printf("v: 0x%x\n",bus_r(FPGA_VERSION_REG)); + printf("fp: 0x%x\n",bus_r(FIX_PATT_REG)); + + //checktype + if (checkType) { + printf("Bus test... (checktype is %d; b is %d)",checkType,b ); + for (i=0; i<1000000; i++) { + bus_w(SET_DELAY_LSB_REG, i*100); + bus_r(FPGA_VERSION_REG); + if (i*100!=bus_r(SET_DELAY_LSB_REG)) + printf("ERROR: wrote 0x%x, read 0x%x\n",i*100,bus_r(SET_DELAY_LSB_REG)); + } + printf("Finished\n"); + }else + printf("(checktype is %d; b is %d)",checkType,b ); + + + //confirm the detector type + switch ((bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>>DETECTOR_TYPE_OFFSET) { + case MOENCH03_MODULE_ID: + myDetectorType=MOENCH; + printf("This is a MOENCH03 module %d\n",MOENCH); + break; + + case JUNGFRAU_MODULE_ID: + myDetectorType=JUNGFRAU; + printf("This is a Jungfrau module %d\n", JUNGFRAU); + break; + + case JUNGFRAU_CTB_ID: + myDetectorType=JUNGFRAUCTB; + printf("This is a Jungfrau CTB %d\n", JUNGFRAUCTB); + break; + + default: + myDetectorType=GENERIC; + printf("Unknown detector type %02x\n",(bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>>DETECTOR_TYPE_OFFSET); + break; + + } + printf("Detector type is %d\n", myDetectorType); + + + //control server only-- + if (b) { + resetPLL(); + bus_w16(CONTROL_REG, SYNC_RESET); + bus_w16(CONTROL_REG, 0); + bus_w16(CONTROL_REG, GB10_RESET_BIT); + bus_w16(CONTROL_REG, 0); + +#ifdef MCB_FUNCS + printf("\nBoard Revision:0x%x\n",(bus_r(PCB_REV_REG)&BOARD_REVISION_MASK)); + if(myDetectorType == JUNGFRAU) + initDetector(); /*allocating detectorModules, detectorsDacs etc for "settings", also does allocate RAM*/ + dataBytes=NMAXMOD*N_CHIP*N_CHAN*2; /**Nchip and Nchan real values get assigned in initDetector()*/ + printf("Initializing Detector\n"); + //bus_w16(CONTROL_REG, SYNC_RESET); // reset registers +#endif + + // testFpga(); + // testRAM(); + // printf("ADC_SYNC_REG:%x\n",bus_r(ADC_SYNC_REG)); + //moench specific + // setPhaseShiftOnce(); + /*some registers set, which is in common with jungfrau, please check */ + prepareADC(); + //setADC(-1); //already does setdaqreg and clean fifo + // setSettings(GET_SETTINGS,-1); + /*some registers set, which is in common with jungfrau, please check */ + initDac(0); initDac(8); //initializes the two dacs + + if(myDetectorType==JUNGFRAU){ + /** for jungfrau reinitializing macro */ + N_CHAN=JUNGFRAU_NCHAN; + N_CHIP=JUNGFRAU_NCHIP; + N_DAC=JUNGFRAU_NDAC; + N_ADC=JUNGFRAU_NADC; + N_CHANS=JUNGFRAU_NCHANS; + + + //set dacs + int retval = -1; + int dacvalues[14][2]={ + {0, 1250}, //vout_cm + {10, 1053}, //vin_com + {1, 600}, //vb_sda + {11, 1000}, //vb_colbuf + {2, 3000}, //vb_test_cur + {3, 830}, //vcascp_pixbuf + {4, 1630}, //vcascn_pixbuf + {12, 750}, //vb_pixbuf + {6, 480}, //vref_ds + {5, 1000}, //vb_ds + {7, 400}, //vref_comp + {13, 1220}, //vb_comp + {8, 1500}, //vref_prech + {9, 3000}, //vdd_prot + }; + for(i=0;i<14;++i){ + retval=setDac(dacvalues[i][0], dacvalues[i][1]); + if(retval!=dacvalues[i][1]) + printf("Error: Setting dac %d failed, wrote %d, read %d\n",dacvalues[i][0],dacvalues[i][1],retval); + } + + //power on the chips + bus_w(POWER_ON_REG,0x1); + + //reset adc + writeADC(ADCREG1,0x3); writeADC(ADCREG1,0x0); + writeADC(ADCREG2,0x40); + writeADC(ADCREG3,0xf); + writeADC(ADCREG4,0x3f); + //vrefs - configurable? + writeADC(ADCREG_VREFS,0x2); + + + //set ADCINVERSionreg (by trial and error) + bus_w(ADC_INVERSION_REG,0x453b2a9c); + + //set adc_pipeline + bus_w(ADC_PIPELINE_REG,0x20); //same as ADC_OFFSET_REG + + //set dbit_pipeline + bus_w(DBIT_PIPELINE_REG,0x100e); + usleep(1000000);//1s + + //reset mem machine fifos fifos + bus_w(MEM_MACHINE_FIFOS_REG,0x4000); + bus_w(MEM_MACHINE_FIFOS_REG,0x0); + + //reset run control + bus_w(MEM_MACHINE_FIFOS_REG,0x0400); + bus_w(MEM_MACHINE_FIFOS_REG,0x0); + + //set default setting + setSettings(DYNAMICGAIN,-1); + } + + + //Initialization of acquistion parameters + setFrames(-1); + setTrains(-1); + setExposureTime(-1); + setPeriod(-1); + setDelay(-1); + setGates(-1); + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + setMaster(GET_MASTER); + setSynchronization(GET_SYNCHRONIZATION_MODE); + startReceiver(0); //firmware + }//end of control server only-- + else printf("\n\n"); + + + //common for both control and stop server + strcpy(mess,"dummy message"); + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + lockStatus=0; + // getDynamicRange(); + + /* both these functions setROI and allocateRAM should go into the control server part. */ + if(myDetectorType!=JUNGFRAU){ + int retvalsize,ret; + setROI(-1,NULL,&retvalsize,&ret); + allocateRAM(); + } + + return OK; +} + + +int decode_function(int file_des) { + int fnum,n; + int retval=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveDataOnly(file_des,&fnum,sizeof(fnum)); + if (n <= 0) { +#ifdef VERBOSE + printf("ERROR reading from socket %d, %d %d\n", n, fnum, file_des); +#endif + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif + +#ifdef VERBOSE + printf( "calling function fnum = %d %x %x %x\n",fnum,(unsigned int)(flist[fnum]), (unsigned int)(flist[F_READ_REGISTER]),(unsigned int)(&read_register)); +#endif + if (fnum<0 || fnum>255) + fnum=255; + retval=(*flist[fnum])(file_des); + if (retval==FAIL) + printf( "Error executing the function = %d \n",fnum); + return retval; +} + + +int function_table() { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_EXEC_COMMAND]=&exec_command; + flist[F_GET_DETECTOR_TYPE]=&get_detector_type; + flist[F_SET_NUMBER_OF_MODULES]=&set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES]=&get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG]=&set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE]=&set_external_communication_mode; + flist[F_GET_ID]=&get_id; + flist[F_DIGITAL_TEST]=&digital_test; + flist[F_WRITE_REGISTER]=&write_register; + flist[F_READ_REGISTER]=&read_register; + flist[F_SET_DAC]=&set_dac; + flist[F_GET_ADC]=&get_adc; + flist[F_SET_CHANNEL]=&set_channel; + flist[F_SET_CHIP]=&set_chip; + flist[F_SET_MODULE]=&set_module; + flist[F_GET_CHANNEL]=&get_channel; + flist[F_GET_CHIP]=&get_chip; + flist[F_GET_MODULE]=&get_module; + flist[F_GET_THRESHOLD_ENERGY]=&get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY]=&set_threshold_energy; + flist[F_SET_SETTINGS]=&set_settings; + flist[F_START_ACQUISITION]=&start_acquisition; + flist[F_STOP_ACQUISITION]=&stop_acquisition; + flist[F_START_READOUT]=&start_readout; + flist[F_GET_RUN_STATUS]=&get_run_status; + flist[F_READ_FRAME]=&read_frame; + flist[F_READ_ALL]=&read_all; + flist[F_START_AND_READ_ALL]=&start_and_read_all; + flist[F_SET_TIMER]=&set_timer; + flist[F_GET_TIME_LEFT]=&get_time_left; + flist[F_SET_DYNAMIC_RANGE]=&set_dynamic_range; + flist[F_SET_ROI]=&set_roi; + flist[F_SET_SPEED]=&set_speed; + flist[F_SET_READOUT_FLAGS]=&set_readout_flags; + flist[F_EXECUTE_TRIMMING]=&execute_trimming; + flist[F_LOCK_SERVER]=&lock_server; + flist[F_SET_PORT]=&set_port; + flist[F_GET_LAST_CLIENT_IP]=&get_last_client_ip; + flist[F_UPDATE_CLIENT]=&update_client; + flist[F_CONFIGURE_MAC]=&configure_mac; + flist[F_LOAD_IMAGE]=&load_image; + flist[F_SET_MASTER]=&set_master; + flist[F_SET_SYNCHRONIZATION_MODE]=&set_synchronization; + flist[F_READ_COUNTER_BLOCK]=&read_counter_block; + flist[F_RESET_COUNTER_BLOCK]=&reset_counter_block; + flist[F_START_RECEIVER]=&start_receiver; + flist[F_STOP_RECEIVER]=&stop_receiver; + flist[F_CALIBRATE_PEDESTAL]=&calibrate_pedestal; + flist[F_SET_CTB_PATTERN]=&set_ctb_pattern; + flist[F_WRITE_ADC_REG]=&write_adc_register; + return OK; +} + + +int M_nofunc(int file_des){ + + int ret=FAIL; + sprintf(mess,"Unrecognized Function\n"); + printf(mess); + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + + +int exit_server(int file_des) { + int retval=FAIL; + sendDataOnly(file_des,&retval,sizeof(retval)); + printf("closing server."); + sprintf(mess,"closing server"); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + +int exec_command(int file_des) { + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int retval=OK; + int sysret=0; + int n=0; + + /* receive arguments */ + n = receiveDataOnly(file_des,cmd,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + if (lockStatus==0 || differentClients==0) + sysret=system(cmd); + + //should be replaced by popen + if (sysret==0) { + sprintf(answer,"Succeeded\n"); + if (lockStatus==1 && differentClients==1) + sprintf(answer,"Detector locked by %s\n", lastClientIP); + } else { + sprintf(answer,"Failed\n"); + retval=FAIL; + } + } else { + sprintf(answer,"Could not receive the command\n"); + } + + /* send answer */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + n = sendDataOnly(file_des,answer,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + + /*return ok/fail*/ + return retval; + +} + + + +int get_detector_type(int file_des) { + int n=0; + enum detectorType ret; + int retval=OK; + + sprintf(mess,"Can't return detector type\n"); + + + /* receive arguments */ + /* execute action */ + ret=myDetectorType; + +#ifdef VERBOSE + printf("Returning detector type %d\n",ret); +#endif + + /* send answer */ + /* send OK/failed */ + if (differentClients==1) + retval=FORCE_UPDATE; + + n += sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + + +} + + +int set_number_of_modules(int file_des) { + int n; + int arg[2], ret=0; + int retval=OK; + int dim, nm; + + sprintf(mess,"Can't set number of modules\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket %d", n); + retval=GOODBYE; + } + if (retval==OK) { + dim=arg[0]; + nm=arg[1]; + + /* execute action */ +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + + //if (nm!=GET_FLAG) { + if (dim!=X && nm!=GET_FLAG) { + retval=FAIL; + sprintf(mess,"Can't change module number in dimension %d\n",dim); + } else { + if (lockStatus==1 && differentClients==1 && nm!=GET_FLAG) { + sprintf(mess,"Detector locked by %s\n", lastClientIP); + retval=FAIL; + } else { + ret=setNMod(nm); + if (nModX==nm || nm==GET_FLAG) { + retval=OK; + if (differentClients==1) + retval=FORCE_UPDATE; + } else + retval=FAIL; + } + } + } + /*} else { + if (dim==Y) { + ret=nModY; + } else if (dim==X) { + ret=setNMod(-1); + } + } + */ + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + +} + + +int get_max_number_of_modules(int file_des) { + int n; + int ret; + int retval=OK; + enum dimension arg; + + sprintf(mess,"Can't get max number of modules\n"); + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* execute action */ +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif + + + switch (arg) { + case X: + ret=getNModBoard(); + break; + case Y: + ret=NMAXMODY; + break; + default: + ret=FAIL; + retval=FAIL; + break; + } +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,ret ); +#endif + + + + if (differentClients==1 && retval==OK) { + retval=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + + /*return ok/fail*/ + return retval; +} + + +//index 0 is in gate +//index 1 is in trigger +//index 2 is out gate +//index 3 is out trigger + +int set_external_signal_flag(int file_des) { + int n; + int arg[2]; + int ret=OK; + int signalindex; + enum externalSignalFlag flag, retval; + + sprintf(mess,"Can't set external signal flag\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + retval=SIGNAL_OFF; + if (ret==OK) { + signalindex=arg[0]; + flag=arg[1]; + /* execute action */ + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + + default: + if (differentClients==0 || lockStatus==0) { + retval=setExtSignal(signalindex,flag); + } else { + if (lockStatus!=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n", lastClientIP); + } + } + + } + +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag ); + printf("Set to flag %d\n",retval); +#endif + + } else { + ret=FAIL; + } + + if (ret==OK && differentClients!=0) + ret=FORCE_UPDATE; + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + +int set_external_communication_mode(int file_des) { + int n; + enum externalCommunicationMode arg, ret=GET_EXTERNAL_COMMUNICATION_MODE; + int retval=OK; + + sprintf(mess,"Can't set external communication mode\n"); + + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* + enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE + }; + */ + if (retval==OK) { + /* execute action */ + + ret=setTiming(arg); + + /* switch(arg) { */ + /* default: */ + /* sprintf(mess,"The meaning of single signals should be set\n"); */ + /* retval=FAIL; */ + /* } */ + + +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif + } else + ret=FAIL; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return retval; +} + + + +int get_id(int file_des) { + // sends back 64 bits! + int64_t retval=-1; + int ret=OK; + int n=0; + enum idMode arg; + + sprintf(mess,"Can't return id\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + + switch (arg) { + case DETECTOR_SERIAL_NUMBER: + retval=getDetectorNumber(); + break; + case DETECTOR_FIRMWARE_VERSION: + retval=getFirmwareSVNVersion(); + retval=(retval <<32) | getFirmwareVersion(); + break; + case DETECTOR_SOFTWARE_VERSION: + retval= SVNREV; + retval= (retval <<32) | SVNDATE; + break; +/* case DETECTOR_FIRMWARE_SVN_VERSION: + retval=getFirmwareSVNVersion(); + break;*/ + default: + printf("Required unknown id %d \n", arg); + ret=FAIL; + retval=FAIL; + break; + } + +#ifdef VERBOSE + printf("Id is %llx\n", retval); +#endif + + if (differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int digital_test(int file_des) { + + int retval; + int ret=OK; + int imod=-1; + int n=0; + int ibit=0; + int ow; + int ival; + enum digitalTestMode arg; + + sprintf(mess,"Can't send digital test\n"); + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Digital test mode %d\n",arg ); +#endif + + switch (arg) { + case CHIP_TEST: + n = receiveDataOnly(file_des,&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + retval=0; +#ifdef MCB_FUNCS + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + break; + } + if (imod >= nModX) { + ret=FAIL; + sprintf(mess,"Module %d disabled\n",imod); + break; + } + if (testShiftIn(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftOut(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftStSel(imod)) retval|=(1<<(ibit)); + ibit++; + //if ( testDataInOut(0x123456, imod)) retval|=(1<<(ibit++)); + //if ( testExtPulse(imod)) retval|=(1<<(ibit++)); + // for (ow=0; ow<6; ow++) + // ow=1; + //#ifndef PICASSOD + for (ow=0; ow<5; ow++) { + //#endif + if (testDataInOutMux(imod, ow, 0x789abc)) retval|=(1<=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + + + + +#ifdef MCB_FUNCS + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + if (ind2500) + val=-1; + printf("%d mV is ",val); + if (val>0) + val=val/2500*4095; + printf("%d DACu\n", val); + } else if (val>4095) + val=-1; + + + retval=setDac(ind,val); + } else { + switch (ind) { + case ADC_VPP: + + printf("Setting ADC VPP to %d\n",val); + if (val>4 || val<0) + printf("Cannot set ADC VPP to %d\n",val); + else { + writeADC(0x18,val); + adcvpp=val; + } + retval=adcvpp;; + break; + + case HV_NEW: + retval=initHighVoltageByModule(val,imod); + break; + + case V_POWER_A: + case V_POWER_B: + case V_POWER_C: + case V_POWER_D: + case V_POWER_IO: + case V_POWER_CHIP: + if (mV) { + retval=setPower(ind,val); + } else + printf("********power %d should be set in mV instead od DACu", ind); + break; + + + default: + printf("**********No dac with index %d\n",ind); + ret=FAIL; + } + + } + } + } + if(ret==OK){ + if (ind=getNModBoard() || imod<0) + ret=FAIL; + +#ifdef MCB_FUNCS + switch (ind) { + case TEMPERATURE_FPGA: + idac=TEMP_FPGA; + break; + case TEMPERATURE_ADC: + idac=TEMP_ADC; + break; + default: + printf("Unknown DAC index %d\n",ind); + sprintf(mess,"Unknown DAC index %d\n",ind); + ret=FAIL; + break; + } + + if (ret==OK) + retval=getTemperatureByModule(idac,imod); +#endif + +#ifdef VERBOSE + printf("ADC is %d V\n", retval); +#endif + if (ret==FAIL) { + printf("Getting adc %d of module %d failed\n", ind, imod); + } + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int set_channel(int file_des) { + int ret=OK; + sls_detector_channel myChan; + int retval; + int n; + + + sprintf(mess,"Can't set channel\n"); + +#ifdef VERBOSE + printf("Setting channel\n"); +#endif + ret=receiveChannel(file_des, &myChan); + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif + + if (ret==OK) { + if (myChan.module>=getNModBoard()) + ret=FAIL; + if (myChan.chip>=N_CHIP) + ret=FAIL; + if (myChan.chan>=N_CHAN) + ret=FAIL; + if (myChan.module<0) + myChan.module=ALLMOD; + } + + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChannelbyNumber(myChan); +#endif + } + } + /* Maybe this is done inside the initialization funcs */ + //copyChannel(detectorChans[myChan.module][myChan.chip]+(myChan.chan), &myChan); + + + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + + +int get_channel(int file_des) { + + int ret=OK; + sls_detector_channel retval; + + int arg[3]; + int ichan, ichip, imod; + int n; + + sprintf(mess,"Can't get channel\n"); + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichan=arg[0]; + ichip=arg[1]; + imod=arg[2]; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0 && ichan=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + + if (ret==OK) { + if (myChip.module>=getNModBoard()) + ret=FAIL; + if (myChip.module<0) + myChip.module=ALLMOD; + if (myChip.chip>=N_CHIP) + ret=FAIL; + } + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChipbyNumber(myChip); +#endif + } + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + return ret; +} + +int get_chip(int file_des) { + + + int ret=OK; + sls_detector_chip retval; + int arg[2]; + int ichip, imod; + int n; + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichip=arg[0]; + imod=arg[1]; + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0) + ret=OK; + else + ret=FAIL; + + +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#endif + + if (ret==OK) { + if (myModule.module>=getNModBoard()) { + ret=FAIL; + printf("Module number is too large %d\n",myModule.module); + } + if (myModule.module<0) + myModule.module=ALLMOD; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initModulebyNumber(myModule); + if(retval != myModule.reg) + ret = FAIL; +#endif + } + } + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + free(myDac); + if(myAdc != NULL) free(myAdc); + if(myChip != NULL) free(myChip); + if(myChan != NULL) free(myChan); + + + //setDynamicRange(dr); always 16 commented out + + return ret; +} + + + + +int get_module(int file_des) { + + int ret=OK; + int arg; + int imod; + int n; + sls_detector_module myModule; + int *myDac=malloc(N_DAC*sizeof(int)); + int *myChip=NULL; + int *myChan=NULL; + int *myAdc=NULL; + + /*not required for jungfrau. so save memory*/ + if(myDetectorType != JUNGFRAU){ + myChip=malloc(N_CHIP*sizeof(int)); + myChan=malloc(N_CHIP*N_CHAN*sizeof(int)); + myAdc=malloc(N_ADC*sizeof(int)); + } + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + + + myModule.adcs=NULL; + myModule.chipregs=NULL; + myModule.chanregs=NULL; + /*not required for jungfrau. so save memory*/ + if(myDetectorType != JUNGFRAU){ + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } + } + + myModule.ndac=N_DAC; + myModule.nchip=N_CHIP; + myModule.nchan=N_CHAN*N_CHIP; + myModule.nadc=N_ADC; + + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + imod=arg; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod-1) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + if (differentClients) + dataret=FORCE_UPDATE; + } +#ifdef VERBOSE + printf("Frames left %d\n",(int)(getFrames())); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + } + + + + + return dataret; + +} + + + + + + + + +int read_all(int file_des) { + +while(read_frame(file_des)==OK) { + +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + return OK; + + +} + +int start_and_read_all(int file_des) { + //int dataret=OK; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + if (differentClients==1 && lockStatus==1) { + dataret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return dataret; + + } + + startStateMachine(); + + /* ret=startStateMachine(); + if (ret!=OK) { + sprintf(mess,"could not start state machine\n"); + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + #ifdef VERBOSE + printf("could not start state machine\n"); +#endif +} else {*/ + read_all(file_des); +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + //} + + + return OK; + + +} + +int set_timer(int file_des) { + enum timerIndex ind; + int64_t tns; + int n; + int64_t retval; + int ret=OK; + + + sprintf(mess,"can't set timer\n"); + + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&tns,sizeof(tns)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret!=OK) { + printf(mess); + } + +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif + if (ret==OK) { + + if (differentClients==1 && lockStatus==1 && tns!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch(ind) { + case FRAME_NUMBER: + retval=setFrames(tns); + break; + case ACQUISITION_TIME: + retval=setExposureTime(tns); + break; + case FRAME_PERIOD: + retval=setPeriod(tns); + break; + case DELAY_AFTER_TRIGGER: + retval=setDelay(tns); + break; + case GATES_NUMBER: + retval=setGates(tns); + break; + case PROBES_NUMBER: + sprintf(mess,"can't set timer for moench\n"); + ret=FAIL; + break; + case CYCLES_NUMBER: + retval=setTrains(tns); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + } + if (ret!=OK) { + printf(mess); + if (differentClients) + ret=FORCE_UPDATE; + } + + if (ret!=OK) { + printf(mess); + printf("set timer failed\n"); + } else if (ind==FRAME_NUMBER) { + // ret=allocateRAM(); + // if (ret!=OK) + // sprintf(mess, "could not allocate RAM for %lld frames\n", tns); + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { +#ifdef VERBOSE + printf("returning ok %d\n",(int)(sizeof(retval))); +#endif + + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + + return ret; + +} + + + + + + + + +int get_time_left(int file_des) { + + enum timerIndex ind; + int n; + int64_t retval; + int ret=OK; + + sprintf(mess,"can't get timer\n"); + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + //#ifdef VERBOSE + + printf("getting time left on timer %d \n",ind); + //#endif + + if (ret==OK) { + switch(ind) { + case FRAME_NUMBER: + printf("getting frames \n"); + retval=getFrames(); + break; + case ACQUISITION_TIME: + retval=getExposureTime(); + break; + case FRAME_PERIOD: + retval=getPeriod(); + break; + case DELAY_AFTER_TRIGGER: + retval=getDelay(); + break; + case GATES_NUMBER: + retval=getGates(); + break; + case PROBES_NUMBER: + retval=getProbes(); + break; + case CYCLES_NUMBER: + retval=getTrains(); + break; + case PROGRESS: + retval=getProgress(); + break; + case ACTUAL_TIME: + retval=getActualTime(); + break; + case MEASUREMENT_TIME: + retval=getMeasurementTime(); + break; + case FRAMES_FROM_START: + case FRAMES_FROM_START_PG: + retval=getFramesFromStart(); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + + + if (ret!=OK) { + printf("get time left failed\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + + //#ifdef VERBOSE + + printf("time left on timer %d is %lld\n",ind, retval); + //#endif + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } else + n = sendDataOnly(file_des,&retval,sizeof(retval)); + +#ifdef VERBOSE + + printf("data sent\n"); +#endif + + return ret; + + +} + +int set_dynamic_range(int file_des) { + + + + int dr; + int n; + int retval; + int ret=OK; + + printf("Set dynamic range?\n"); + sprintf(mess,"can't set dynamic range\n"); + + + n = receiveDataOnly(file_des,&dr,sizeof(dr)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + if (differentClients==1 && lockStatus==1 && dr>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setDynamicRange(dr); + } + + //if (dr>=0 && retval!=dr) ret=FAIL; + if (ret!=OK) { + sprintf(mess,"set dynamic range failed\n"); + } else { + /* ret=allocateRAM(); */ +/* if (ret!=OK) */ +/* sprintf(mess,"Could not allocate RAM for the dynamic range selected\n"); */ +// else + if (differentClients) + ret=FORCE_UPDATE; + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + +int set_roi(int file_des) { + + int i; + int ret=OK; + int nroi=-1; + int n=0; + int retvalsize=0; + ROI arg[MAX_ROIS]; + ROI* retval=0; + strcpy(mess,"Could not set/get roi\n"); + // u_int32_t disable_reg=0; + + n = receiveDataOnly(file_des,&nroi,sizeof(nroi)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if(myDetectorType == JUNGFRAU){ + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); + printf("Error:Set ROI-%s",mess); + } + + else{ + + if(nroi>=0){ + n = receiveDataOnly(file_des,arg,nroi*sizeof(ROI)); + if (n != (nroi*sizeof(ROI))) { + sprintf(mess,"Received wrong number of bytes for ROI\n"); + ret=FAIL; + } + + printf("Setting ROI to:"); + for( i=0;i=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch (arg) { + case CLOCK_DIVIDER: + retval=setClockDivider(val,0); + break; + +/* case PHASE_SHIFT: */ +/* retval=phaseStep(val,0); */ +/* break; */ + + case OVERSAMPLING: + retval=setOversampling(val); + break; + + case ADC_CLOCK: + retval=setClockDivider(val,1); + break; + +/* case ADC_PHASE: */ +/* retval=phaseStep(val,1); */ +/* break; */ + + + case ADC_PIPELINE: + retval=adcPipeline(val); + break; + + + + default: + ret=FAIL; + sprintf(mess,"Unknown speed parameter %d",arg); + } + } + } + + + } + + + switch (arg) { + case CLOCK_DIVIDER: + retval=getClockDivider(0); + break; + + case PHASE_SHIFT: + retval=getPhase(); + // retval=phaseStep(-1); + //ret=FAIL; + //sprintf(mess,"Cannot read phase",arg); + break; + + case OVERSAMPLING: + retval=setOversampling(-1); + break; + + case ADC_CLOCK: + retval=getClockDivider(1); + break; + + case ADC_PHASE: + retval=getPhase(); + break; + + + case ADC_PIPELINE: + retval=adcPipeline(-1); + break; + + + default: + ret=FAIL; + sprintf(mess,"Unknown speed parameter %d",arg); + } + } + + + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + +int set_readout_flags(int file_des) { + + enum readOutFlags arg; + int ret=FAIL; + + + receiveDataOnly(file_des,&arg,sizeof(arg)); + + sprintf(mess,"can't set readout flags for moench\n"); + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + return ret; +} + + + + + +int execute_trimming(int file_des) { + + int arg[3]; + int ret=FAIL; + enum trimMode mode; + + sprintf(mess,"can't set execute trimming for moench\n"); + + receiveDataOnly(file_des,&mode,sizeof(mode)); + receiveDataOnly(file_des,arg,sizeof(arg)); + + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + return ret; +} + + +int lock_server(int file_des) { + + + int n; + int ret=OK; + + int lock; + n = receiveDataOnly(file_des,&lock,sizeof(lock)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (lock)\n"); + ret=FAIL; + } + if (lock>=0) { + if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) + lockStatus=lock; + else { + ret=FAIL; + sprintf(mess,"Server already locked by %s\n", lastClientIP); + } + } + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else + n = sendDataOnly(file_des,&lockStatus,sizeof(lockStatus)); + + return ret; + +} + +int set_port(int file_des) { + int n; + int ret=OK; + int sd=-1; + + enum portType p_type; /** data? control? stop? Unused! */ + int p_number; /** new port number */ + + n = receiveDataOnly(file_des,&p_type,sizeof(p_type)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (ptype)\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&p_number,sizeof(p_number)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (pnum)\n"); + ret=FAIL; + } + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + printf("\n"); + ret=FAIL; + } + + printf("set port %d to %d\n",p_type, p_number); + + sd=bindSocket(p_number); + } + if (sd>=0) { + ret=OK; + if (differentClients ) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + printf("Could not bind port %d\n", p_number); + if (sd==-10) { + sprintf(mess,"Port %d already set\n", p_number); + printf("Port %d already set\n", p_number); + + } + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&p_number,sizeof(p_number)); + closeConnection(file_des); + exitServer(sockfd); + sockfd=sd; + + } + + return ret; + +} + +int get_last_client_ip(int file_des) { + int ret=OK; + int n; + if (differentClients ) + ret=FORCE_UPDATE; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + + return ret; + +} + + +int send_update(int file_des) { + + int ret=OK; + enum detectorSettings t; + int n;//int thr, n; + //int it; + int64_t retval, tns=-1; + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + n = sendDataOnly(file_des,&nModX,sizeof(nModX)); + n = sendDataOnly(file_des,&nModY,sizeof(nModY)); + n = sendDataOnly(file_des,&dynamicRange,sizeof(dynamicRange)); + n = sendDataOnly(file_des,&dataBytes,sizeof(dataBytes)); + t=setSettings(GET_SETTINGS,-1); + n = sendDataOnly(file_des,&t,sizeof(t)); +/* thr=getThresholdEnergy(); + n = sendDataOnly(file_des,&thr,sizeof(thr));*/ + retval=setFrames(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setExposureTime(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setPeriod(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setDelay(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setGates(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); +/* retval=setProbes(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t));*/ + retval=setTrains(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + + if (lockStatus==0) { + strcpy(lastClientIP,thisClientIP); + } + + return ret; + + +} +int update_client(int file_des) { + + int ret=OK; + + sendDataOnly(file_des,&ret,sizeof(ret)); + return send_update(file_des); + + + +} + + +int configure_mac(int file_des) { + + int ret=OK; + char arg[5][50]; + int n; + + int imod=0;//should be in future sent from client as -1, arg[2] + int ipad; + long long int imacadd; + long long int idetectormacadd; + int udpport; + int detipad; + int retval=-100; + + sprintf(mess,"Can't configure MAC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + sscanf(arg[0], "%x", &ipad); + sscanf(arg[1], "%llx", &imacadd); + sscanf(arg[2], "%x", &udpport); + sscanf(arg[3], "%llx", &idetectormacadd); + sscanf(arg[4], "%x", &detipad); + + //#ifdef VERBOSE + int i; + printf("\ndigital_test_bit in server %d\t",digitalTestBit); + printf("\nipadd %x\t",ipad); + printf("destination ip is %d.%d.%d.%d = 0x%x \n",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff,ipad); + printf("macad:%llx\n",imacadd); + for (i=0;i<6;i++) + printf("mac adress %d is 0x%x \n",6-i,(unsigned int)(((imacadd>>(8*i))&0xFF))); + printf("udp port:0x%x\n",udpport); + printf("detector macad:%llx\n",idetectormacadd); + for (i=0;i<6;i++) + printf("detector mac adress %d is 0x%x \n",6-i,(unsigned int)(((idetectormacadd>>(8*i))&0xFF))); + printf("detipad %x\n",detipad); + printf("\n"); + //#endif + + + + if (imod>=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + + //#ifdef VERBOSE + printf("Configuring MAC of module %d at port %x\n", imod, udpport); + //#endif +#ifdef MCB_FUNCS + if (ret==OK){ + if(runBusy()){ + ret=stopStateMachine(); + if(ret==FAIL) + strcpy(mess,"could not stop detector acquisition to configure mac"); + } + + if(ret==OK) + configureMAC(ipad,imacadd,idetectormacadd,detipad,digitalTestBit,udpport); + retval=getAdcConfigured(); + } +#endif + if (ret==FAIL) + printf("configuring MAC of mod %d failed\n", imod); + else + printf("Configuremac successful of mod %d and adc %d\n",imod,retval); + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + /*return ok/fail*/ + return ret; + +} + + + +int load_image(int file_des) { + int retval; + int ret=OK; + int n; + enum imageType index; + short int ImageVals[N_CHAN*N_CHIP]; + + sprintf(mess,"Loading image failed\n"); + + n = receiveDataOnly(file_des,&index,sizeof(index)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,ImageVals,dataBytes); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + switch (index) { + case DARK_IMAGE : +#ifdef VERBOSE + printf("Loading Dark image\n"); +#endif + break; + case GAIN_IMAGE : +#ifdef VERBOSE + printf("Loading Gain image\n"); +#endif + break; + default: + printf("Unknown index %d\n",index); + sprintf(mess,"Unknown index %d\n",index); + ret=FAIL; + break; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + retval=loadImage(index,ImageVals); + if (retval==-1) + ret = FAIL; + } + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + +int set_master(int file_des) { + + enum masterFlags retval=GET_MASTER; + enum masterFlags arg; + int n; + int ret=OK; + // int regret=OK; + + + sprintf(mess,"can't set master flags\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setMaster(arg); + + } + if (retval==GET_MASTER) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int set_synchronization(int file_des) { + + enum synchronizationMode retval=GET_MASTER; + enum synchronizationMode arg; + int n; + int ret=OK; + //int regret=OK; + + + sprintf(mess,"can't set synchronization mode\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + //ret=setStoreInRAM(0); + // initChipWithProbes(0,0,0, ALLMOD); + retval=setSynchronization(arg); + } + if (retval==GET_SYNCHRONIZATION_MODE) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int read_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + //char *retval=NULL; + short int CounterVals[N_CHAN*N_CHIP]; + + sprintf(mess,"Read counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + ret=readCounterBlock(startACQ,CounterVals); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,CounterVals[i]); +#endif + } + } + + if(ret!=FAIL){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,CounterVals,dataBytes);//1280*2 + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + + + +int reset_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + + sprintf(mess,"Reset counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=resetCounterBlock(startACQ); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + + /*return ok/fail*/ + return ret; +} + + + + + + +int start_receiver(int file_des) { + int ret=OK; + int n=0; + strcpy(mess,"Could not start receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret = startReceiver(1); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + + +int stop_receiver(int file_des) { + int ret=OK; + int n=0; + + strcpy(mess,"Could not stop receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret=startReceiver(0); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + +int calibrate_pedestal(int file_des){ + + int ret=OK; + int retval=-1; + int n; + int frames; + + sprintf(mess,"Could not calibrate pedestal\n"); + + n = receiveDataOnly(file_des,&frames,sizeof(frames)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=calibratePedestal(frames); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + + /*return ok/fail*/ + return ret; +} + + +int set_ctb_pattern(int file_des){ + + int ret=OK;//FAIL; + int retval=-1; + int n; + int mode; + uint64_t word, retval64, t; + int addr; + int level, start, stop, nl; + uint64_t pat[1024]; + + sprintf(mess,"Could not set pattern\n"); + + n = receiveDataOnly(file_des,&mode,sizeof(mode)); + printf("pattern mode is %d\n",mode); + switch (mode) { + + case 0: //sets word + n = receiveDataOnly(file_des,&addr,sizeof(addr)); + n = receiveDataOnly(file_des,&word,sizeof(word)); + ret=OK; + + switch (addr) { + case -1: + retval64=writePatternIOControl(word); + break; + case -2: + retval64=writePatternClkControl(word); + break; + default: + retval64=writePatternWord(addr,word); + }; + + + //write word; + //@param addr address of the word, -1 is I/O control register, -2 is clk control register + //@param word 64bit word to be written, -1 gets + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval64,sizeof(retval64)); + break; + + case 1: //pattern loop + n = receiveDataOnly(file_des,&level,sizeof(level)); + n = receiveDataOnly(file_des,&start,sizeof(start)); + n = receiveDataOnly(file_des,&stop,sizeof(stop)); + n = receiveDataOnly(file_des,&nl,sizeof(nl)); + + + + printf("level %d start %x stop %x nl %d\n",level, start, stop, nl); + /** Sets the pattern or loop limits in the CTB + @param level -1 complete pattern, 0,1,2, loop level + @param start start address if >=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ + ret=setPatternLoop(level, &start, &stop, &nl); + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else { + n += sendDataOnly(file_des,&start,sizeof(start)); + n += sendDataOnly(file_des,&stop,sizeof(stop)); + n += sendDataOnly(file_des,&nl,sizeof(nl)); + } + break; + + + + case 2: //wait address + n = receiveDataOnly(file_des,&level,sizeof(level)); + n = receiveDataOnly(file_des,&addr,sizeof(addr)); + + + + /** Sets the wait address in the CTB + @param level 0,1,2, wait level + @param addr wait address, -1 gets + @returns actual value + */ + printf("wait addr %d %x\n",level, addr); + retval=setPatternWaitAddress(level,addr); + printf("ret: wait addr %d %x\n",level, retval); + ret=OK; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else { + n += sendDataOnly(file_des,&retval,sizeof(retval)); + + } + + + break; + + + case 3: //wait time + n = receiveDataOnly(file_des,&level,sizeof(level)); + n = receiveDataOnly(file_des,&t,sizeof(t)); + + + /** Sets the wait time in the CTB + @param level 0,1,2, wait level + @param t wait time, -1 gets + @returns actual value + */ + + ret=OK; + + retval64=setPatternWaitTime(level,t); + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval64,sizeof(retval64)); + + break; + + + + case 4: + n = receiveDataOnly(file_des,pat,sizeof(pat)); + for (addr=0; addr<1024; addr++) + writePatternWord(addr,word); + ret=OK; + retval=0; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval64,sizeof(retval64)); + + break; + + + + + + default: + ret=FAIL; + printf(mess); + sprintf(mess,"%s - wrong mode %d\n",mess, mode); + n = sendDataOnly(file_des,&ret,sizeof(ret)); + n += sendDataOnly(file_des,mess,sizeof(mess)); + + + + } + + + /*return ok/fail*/ + return ret; +} + + +int write_adc_register(int file_des) { + + int retval; + int ret=OK; + int arg[2]; + int addr, val; + int n; + + sprintf(mess,"Can't write to register\n"); + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + addr=arg[0]; + val=arg[1]; + +#ifdef VERBOSE + printf("writing to register 0x%x data 0x%x\n", addr, val); +#endif + + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } + + + if(ret!=FAIL){ + ret=writeADC(addr,val); + if (ret==OK) + retval=val; + } + + +#ifdef VERBOSE + printf("Data set to 0x%x\n", retval); +#endif + if (retval==val) { + ret=OK; + if (differentClients) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Writing to register 0x%x failed: wrote 0x%x but read 0x%x\n", addr, val, retval); + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} diff --git a/slsDetectorSoftware/jctbDetectorServer/server_funcs.h b/slsDetectorSoftware/jctbDetectorServer/server_funcs.h new file mode 100755 index 000000000..2d674a1d0 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/server_funcs.h @@ -0,0 +1,98 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H + + +#include "sls_detector_defs.h" + + +#include +/* +#include +#include +#include +*/ +#include "communication_funcs.h" + + + + +#define GOODBYE -200 + +int sockfd; + +int function_table(); + +int decode_function(int); +int init_detector(int,int); + +int M_nofunc(int); +int exit_server(int); + + + + +// General purpose functions +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); + + +int exec_command(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +int write_register(int); +int read_register(int); +int set_dac(int); +int get_adc(int); +int set_channel(int); +int set_chip(int); +int set_module(int); +int get_channel(int); +int get_chip(int); +int get_module(int); + +int get_threshold_energy(int); +int set_threshold_energy(int); +int set_settings(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int read_frame(int); +int read_all(int); +int start_and_read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_roi(int); +int get_roi(int); +int set_speed(int); +int set_readout_flags(int); +int execute_trimming(int); +int lock_server(int); +int set_port(int); +int get_last_client_ip(int); +int set_master(int); +int set_synchronization(int); + +int update_client(int); +int send_update(int); +int configure_mac(int); + +int load_image(int); +int read_counter_block(int); +int reset_counter_block(int); + +int start_receiver(int); +int stop_receiver(int); + + +int calibrate_pedestal(int); + +int set_roi(int); +int set_ctb_pattern(int); + +int write_adc_register(int);; +#endif diff --git a/slsDetectorSoftware/jctbDetectorServer/sharedmemory.c b/slsDetectorSoftware/jctbDetectorServer/sharedmemory.c new file mode 100755 index 000000000..4504cfe05 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/sharedmemory.c @@ -0,0 +1,39 @@ +#include "sharedmemory.h" + +struct statusdata *stdata; + +int inism(int clsv) { + +static int scansmid; + + if (clsv==SMSV) { + if ( (scansmid=shmget(SMKEY,1024,IPC_CREAT | 0666 ))==-1 ) { + return -1; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -2; + } + } + + if (clsv==SMCL) { + if ( (scansmid=shmget(SMKEY,0,0) )==-1 ) { + return -3; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -4; + } + } + return 1; +} + +void write_status_sm(char *status) { + strcpy(stdata->status,status); +} + +void write_stop_sm(int v) { + stdata->stop=v; +} + +void write_runnumber_sm(int v) { + stdata->runnumber=v; +} diff --git a/slsDetectorSoftware/jctbDetectorServer/sharedmemory.h b/slsDetectorSoftware/jctbDetectorServer/sharedmemory.h new file mode 100755 index 000000000..bdbddf719 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/sharedmemory.h @@ -0,0 +1,48 @@ +#ifndef SM +#define SM + +#include "sls_detector_defs.h" + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +/* key for shared memory */ +#define SMKEY 10001 + +#define SMSV 1 +#define SMCL 2 + + +struct statusdata { + int runnumber; + int stop; + char status[20]; +} ; + + +/* for shared memory */ + +int inism(int clsv); +void write_status_sm(char *status); +void write_stop_sm(int v); +void write_runnumber_sm(int v); + +#endif diff --git a/slsDetectorSoftware/jctbDetectorServer/sls_detector_defs.h b/slsDetectorSoftware/jctbDetectorServer/sls_detector_defs.h new file mode 120000 index 000000000..c5062e03f --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/sls_detector_defs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/sls_detector_funcs.h b/slsDetectorSoftware/jctbDetectorServer/sls_detector_funcs.h new file mode 120000 index 000000000..844b67129 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/sls_detector_funcs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/sls_receiver_defs.h b/slsDetectorSoftware/jctbDetectorServer/sls_receiver_defs.h new file mode 120000 index 000000000..1de31caf5 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/sls_receiver_defs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/sls_receiver_funcs.h b/slsDetectorSoftware/jctbDetectorServer/sls_receiver_funcs.h new file mode 120000 index 000000000..c2ea4ded9 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/sls_receiver_funcs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jctbDetectorServer/stop_server.c b/slsDetectorSoftware/jctbDetectorServer/stop_server.c new file mode 100755 index 000000000..e3c8ff7e1 --- /dev/null +++ b/slsDetectorSoftware/jctbDetectorServer/stop_server.c @@ -0,0 +1,46 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + + +#include "sls_detector_defs.h" + + +#include "communication_funcs.h" +#include "firmware_funcs.h" + + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + + portno = DEFAULT_PORTNO; + + + bindSocket(portno); + if (getServerError()) + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + acceptConnection(); + retval=stopStateMachine(); + closeConnection(); + } + + exitServer(); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/jungfrauDetectorServer/.target-makefrag b/slsDetectorSoftware/jungfrauDetectorServer/.target-makefrag new file mode 100755 index 000000000..ce093ecac --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/.target-makefrag @@ -0,0 +1 @@ +AXIS_BUILDTYPE ?= cris-axis-linux-gnu diff --git a/slsDetectorSoftware/jungfrauDetectorServer/Makefile b/slsDetectorSoftware/jungfrauDetectorServer/Makefile new file mode 100755 index 000000000..6b3fc4bd4 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/Makefile @@ -0,0 +1,61 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + + +CROSS = bfin-uclinux- +CC = $(CROSS)gcc + +CFLAGS += -Wall -DMOENCHD -DMCB_FUNCS -DDACS_INT -DDEBUG -DV1 #-DVERBOSE #-DVERYVERBOSE #-DVIRTUAL #-DDACS_INT_CSERVER + + +PROGS= jungfrauDetectorServerTest +INSTDIR= /tftpboot +INSTMODE= 0777 + + + +BINS = testlib_sharedlibc +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + + + +all: clean $(PROGS) + +test: clean jungfrauADCTEst + +boot: $(OBJS) + +jungfrauDetectorServerTest: $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +jungfrauDetectorServer: $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + +jungfrauADCTEst: $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) -DTESTADC + + + + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + + +romfs: + $(ROMFSINST) /bin/$(PROGS) + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/jungfrauDetectorServer/Makefile.virtual b/slsDetectorSoftware/jungfrauDetectorServer/Makefile.virtual new file mode 100755 index 000000000..38dd2537c --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/Makefile.virtual @@ -0,0 +1,30 @@ + +DESTDIR ?= ./ + +CC = gcc +CFLAGS += -Wall -DMOENCHD -DMCB_FUNCS -DDACS_INT -DDEBUG -DVIRTUAL + + +PROGS= $(DESTDIR)/moenchVirtualServer + + +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + +moenchVirtualServer = $(PROGS) + +all: clean $(PROGS) + + +$(PROGS): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/jungfrauDetectorServer/ansi.h b/slsDetectorSoftware/jungfrauDetectorServer/ansi.h new file mode 120000 index 000000000..c8131b6ec --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/ansi.h @@ -0,0 +1 @@ +/afs/psi.ch/project/sls_det_software/dhanya_softwareDevelopment/mySoft/slsDetectorsPackage/slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/communication_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/communication_funcs.c new file mode 120000 index 000000000..87a4f95d1 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/communication_funcs.c @@ -0,0 +1 @@ +../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/communication_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/communication_funcs.h new file mode 120000 index 000000000..f220903b2 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/communication_funcs.h @@ -0,0 +1 @@ +../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c new file mode 100755 index 000000000..1765f4662 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/firmware_funcs.c @@ -0,0 +1,3380 @@ +//#define TESTADC +#define TESTADC1 + + +//#define TIMEDBG +#include "server_defs.h" +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers_m.h" + +//#define VERBOSE +//#define VERYVERBOSE + + +#ifdef SHAREDMEMORY +#include "sharedmemory.h" +#endif + +#include +#include +#include + +#include +#include +#include /* exit() */ +#include /* memset(), memcpy() */ +#include /* uname() */ +#include +#include /* socket(), bind(), + listen(), accept() */ +#include +#include +#include +#include +#include /* fork(), write(), close() */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef struct ip_header_struct { + u_int16_t ip_len; + u_int8_t ip_tos; + u_int8_t ip_ihl:4 ,ip_ver:4; + u_int16_t ip_offset:13,ip_flag:3; + u_int16_t ip_ident; + u_int16_t ip_chksum; + u_int8_t ip_protocol; + u_int8_t ip_ttl; + u_int32_t ip_sourceip; + u_int32_t ip_destip; +} ip_header; + + +struct timeval tss,tse,tsss; //for timing + + +//for memory mapping +u_int32_t CSP0BASE; + + +FILE *debugfp, *datafp; + +int fr; +int wait_time; +int *fifocntrl; + +//int *statusreg; commented out by dhanya +const int nModY=1; +int nModBoard; +int nModX=NMAXMOD; +int dynamicRange=16;//32; +int nSamples=1; + +int dataBytes=NMAXMOD*NCHIP*NCHAN*2; + +int storeInRAM=0; +int ROI_flag=0; +int adcConfigured=-1; +u_int16_t *ram_values=NULL; +char volatile *now_ptr=NULL; +u_int32_t volatile *values; +int ram_size=0; + +int64_t totalTime=1; +u_int32_t progressMask=0; + +int phase_shift=0;//DEFAULT_PHASE_SHIFT; +int ipPacketSize=DEFAULT_IP_PACKETSIZE; +int udpPacketSize=DEFAULT_UDP_PACKETSIZE; + +#ifndef NEW_PLL_RECONFIG +u_int32_t clkDivider[2]={32,16}; +#else +u_int32_t clkDivider[2]={40,20}; +#endif +int32_t clkPhase[2]={0,0}; + +u_int32_t adcDisableMask=0; + +int ififostart, ififostop, ififostep, ififo; + +int masterMode=NO_MASTER, syncMode=NO_SYNCHRONIZATION, timingMode=AUTO_TIMING; + +enum externalSignalFlag signals[4]={EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF}; + +int withGotthard = 0; + +/**is not const because this value will change after initDetector, is removed from mcb_funcs.c cuz its not used anywhere + * why is this used anywhere instead of macro*/ +int nChans=NCHAN; +int nChips=NCHIP; +int nDacs=NDAC; +int nAdcs=NADC; + +extern enum detectorType myDetectorType; +/** for jungfrau reinitializing macro later in server_funcs.c in initDetector*/ +extern int N_CHAN; +extern int N_CHIP; +extern int N_DAC; +extern int N_ADC; +extern int N_CHANS; + +int mapCSP0(void) { + printf("Mapping memory\n"); +#ifndef VIRTUAL + int fd; + fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + printf("\nCan't find /dev/mem!\n"); + return FAIL; + } + printf("/dev/mem opened\n"); + + CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + printf("\nCan't map memmory area!!\n"); + return FAIL; + } + printf("CSP0 mapped\n"); + +#endif +#ifdef VIRTUAL + CSP0BASE = malloc(MEM_SIZE); + printf("memory allocated\n"); +#endif +#ifdef SHAREDMEMORY + if ( (res=inism(SMSV))<0) { + printf("error attaching shared memory! %i",res); + return FAIL; + } +#endif + printf("CSPObase is 0x%08x \n",CSP0BASE); + printf("CSPOBASE=from %08x to %08x\n",CSP0BASE,CSP0BASE+MEM_SIZE); + + u_int32_t address; + address = FIFO_DATA_REG;//_OFF; + values=(u_int32_t*)(CSP0BASE+address*2); + printf("statusreg=%08x\n",bus_r(STATUS_REG)); + printf("\n\n"); + return OK; +} + +u_int16_t bus_r16(u_int32_t offset){ + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + return *ptr1; +} + +u_int16_t bus_w16(u_int32_t offset, u_int16_t data) { + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + *ptr1=data; + return OK; +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_w16(u_int32_t ramType, int adc, int adcCh, int Ch, u_int16_t data) { + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Writing to addr:%x\n",adr); + return bus_w16(adr,data); +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_r16(u_int32_t ramType, int adc, int adcCh, int Ch){ + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Reading from addr:%x\n",adr); + return bus_r16(adr); +} + +u_int32_t bus_w(u_int32_t offset, u_int32_t data) { + volatile u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + *ptr1=data; + + return OK; +} + + +u_int32_t bus_r(u_int32_t offset) { + volatile u_int32_t *ptr1; + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + return *ptr1; +} + + +int setPhaseShiftOnce(){ + u_int32_t addr, reg; + int i; + addr=MULTI_PURPOSE_REG; + reg=bus_r(addr); +#ifdef VERBOSE + printf("Multipurpose reg:%x\n",reg); +#endif + + //Checking if it is power on(negative number) + // if(((reg&0xFFFF0000)>>16)>0){ + //bus_w(addr,0x0); //clear the reg + + if(reg==0){ + printf("\nImplementing phase shift of %d\n",phase_shift); + for (i=1;i2*l) { + h=l+1; + odd=1; + } + printf("Counter %d: Low is %d, High is %d\n",i, l,h); + + + val= (i<<18)| (odd<<17) | l | (h<<8); + + printf("Counter %d, val: %08x\n", i, val); + setPllReconfigReg(PLL_C_COUNTER_REG, val,0); + // usleep(20); + //change sync at the same time as + if (i>0) { + val= (2<<18)| (odd<<17) | l | (h<<8); + + printf("Counter %d, val: %08x\n", i, val); + setPllReconfigReg(PLL_C_COUNTER_REG, val,0); + + } + + } else { + // if (mode==1) { + // } else { + printf("phase in %d\n",clkPhase[1]); + + if (clkPhase[1]>0) { + inv=0; + phase=clkPhase[1]; + } else { + inv=1; + phase=-1*clkPhase[1]; + } + + printf("phase out %d %08x\n",phase,phase); + if (inv) { + val=phase | (1<<16);// | (inv<<21); + printf("**************** phase word %08x\n",val); + + // printf("Phase, val: %08x\n", val); + setPllReconfigReg(PLL_PHASE_SHIFT_REG,val,0); //shifts counter 0 + } else { + + + val=phase ;// | (inv<<21); + printf("**************** phase word %08x\n",val); + + // printf("Phase, val: %08x\n", val); + setPllReconfigReg(PLL_PHASE_SHIFT_REG,val,0); //shifts counter 0 +#ifndef NEW_PLL_RECONFIG + printf("Start reconfig\n"); setPllReconfigReg(PLL_START_REG, 1,0); + + // bus_w(PLL_CNTRL_REG, 0); + printf("Status register\n"); getPllReconfigReg(PLL_STATUS_REG,0); + // sleep(1); + + printf("PLL mode\n"); setPllReconfigReg(PLL_MODE_REG,1,0); + // usleep(10000); + +#endif + printf("**************** phase word %08x\n",val); + + val=phase | (2<<16);// | (inv<<21); + // printf("Phase, val: %08x\n", val); + setPllReconfigReg(PLL_PHASE_SHIFT_REG,val,0); //shifts counter 0 + } + + + } + +#ifndef NEW_PLL_RECONFIG + printf("Start reconfig\n"); setPllReconfigReg(PLL_START_REG, 1,0); + + // bus_w(PLL_CNTRL_REG, 0); + printf("Status register\n"); getPllReconfigReg(PLL_STATUS_REG,0); + // sleep(1); +#endif + // printf("PLL mode\n"); setPllReconfigReg(PLL_MODE_REG,0,0); + usleep(10000); + if (i<2) { + printf("reset pll\n"); + bus_w(PLL_CNTRL_REG,((1<1) + return -1; + + if (ic==1 && d>40) + return -1; + + if (d>160) + return -1; + + if (tot>510) + return -1; + + if (tot<1) + return -1; + + + + clkDivider[ic]=d; + configurePll(ic); + + + + return clkDivider[ic]; +} + + +int phaseStep(int st){ + + if (st>65535 || st<-65535) + return clkPhase[0]; +#ifdef NEW_PLL_RECONFIG + printf("reset pll\n"); + bus_w(PLL_CNTRL_REG,((1<1) + return -1; + return clkDivider[ic]; + + +/* int ic=0; */ +/* u_int32_t val; */ +/* u_int32_t l,h; */ + +/* printf("get clk divider\n"); */ + + +/* setPllReconfigReg(PLL_MODE_REG,1,0); */ +/* getPllReconfigReg(PLL_MODE_REG,0); */ + +/* u_int32_t addr=0xa; //c0 */ +/* if (ic>0) */ +/* addr=0xb; //c1 */ + +/* val=getPllReconfigReg(PLL_N_COUNTER_REG,0); */ +/* printf("Getting N counter %08x\n",val); */ + +/* l=val&0xff; */ +/* h=(val>>8)&0xff; */ + +/* //getPllReconfigReg(PLL_STATUS_REG,0); */ +/* val=getPllReconfigReg(addr,0); */ +/* printf("Getting C counter %08x\n",val); */ + + + +/* return 800/(l+h); */ + +} + + +u_int32_t adcPipeline(int d) { + if (d>=0) + bus_w(DAQ_REG, d); + return bus_r(DAQ_REG)&0xff; +} + + +u_int32_t setSetLength(int d) { + return 0; +} + +u_int32_t getSetLength() { + return 0; +} + +u_int32_t setOversampling(int d) { + + if (d>=0 && d<=255) + bus_w(OVERSAMPLING_REG, d); + + return bus_r(OVERSAMPLING_REG); +} + + +u_int32_t setWaitStates(int d1) { + return 0; +} + +u_int32_t getWaitStates() { + return 0; +} + + +u_int32_t setTotClockDivider(int d) { + return 0; +} + +u_int32_t getTotClockDivider() { + return 0; +} + + +u_int32_t setTotDutyCycle(int d) { + return 0; +} + +u_int32_t getTotDutyCycle() { + return 0; +} + + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode) { + + //int modes[]={EXT_SIG_OFF, EXT_GATE_IN_ACTIVEHIGH, EXT_GATE_IN_ACTIVELOW,EXT_TRIG_IN_RISING,EXT_TRIG_IN_FALLING,EXT_RO_TRIG_IN_RISING, EXT_RO_TRIG_IN_FALLING,EXT_GATE_OUT_ACTIVEHIGH, EXT_GATE_OUT_ACTIVELOW, EXT_TRIG_OUT_RISING, EXT_TRIG_OUT_FALLING, EXT_RO_TRIG_OUT_RISING, EXT_RO_TRIG_OUT_FALLING}; + // int off=d*SIGNAL_OFFSET; + + u_int32_t c; + c=bus_r(EXT_SIGNAL_REG); + + if (d>=0 && d<4) { + signals[d]=mode; +#ifdef VERBOSE + printf("settings signal variable number %d to value %04x\n", d, signals[d]); +#endif + + // if output signal, set it! + + switch (mode) { + case GATE_IN_ACTIVE_HIGH: + case GATE_IN_ACTIVE_LOW: + if (timingMode==GATE_FIX_NUMBER || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case TRIGGER_IN_RISING_EDGE: + case TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_EXPOSURE || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case RO_TRIGGER_IN_RISING_EDGE: + case RO_TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_READOUT) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case MASTER_SLAVE_SYNCHRONIZATION: + setSynchronization(syncMode); + break; + default: + setFPGASignal(d,mode); + break; + } + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + } + + +// if (mode<=RO_TRIGGER_OUT_FALLING_EDGE && mode>=0) +// bus_w(EXT_SIGNAL_REG,((modes[mode])<=0) { +#ifdef VERBOSE + printf("writing signal register number %d mode %04x\n",d, modes[mode]); +#endif + bus_w(EXT_SIGNAL_REG,((modes[mode])<>off); + + if (mode=0 && d<4) { +#ifdef VERBOSE + printf("gettings signal variable number %d value %04x\n", d, signals[d]); +#endif + return signals[d]; + } else + return -1; + + +} + + +int getFPGASignal(int d) { + + int modes[]={SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW,TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE,RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE,RO_TRIGGER_OUT_FALLING_EDGE}; + + int off=d*SIGNAL_OFFSET; + int mode=((bus_r(EXT_SIGNAL_REG)&(SIGNAL_MASK<>off); + + if (mode<=RO_TRIGGER_OUT_FALLING_EDGE) { + if (modes[mode]!=SIGNAL_OFF && signals[d]!=MASTER_SLAVE_SYNCHRONIZATION) + signals[d]=modes[mode]; +#ifdef VERYVERBOSE + printf("gettings signal register number %d value %04x\n", d, modes[mode]); +#endif + return modes[mode]; + } else + return -1; + +} + + + + + +/* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; +*/ + + +int setTiming(int ti) { + + + int ret=GET_EXTERNAL_COMMUNICATION_MODE; + + int g=-1, t=-1, rot=-1; + + int i; + + switch (ti) { + case AUTO_TIMING: + timingMode=ti; + // disable all gates/triggers in except if used for master/slave synchronization + for (i=0; i<4; i++) { + if (getFPGASignal(i)>0 && getFPGASignal(i)=0 && t>=0 && rot<0) { + ret=GATE_WITH_START_TRIGGER; + } else if (g<0 && t>=0 && rot<0) { + ret=TRIGGER_EXPOSURE; + } else if (g>=0 && t<0 && rot<0) { + ret=GATE_FIX_NUMBER; + } else if (g<0 && t<0 && rot>0) { + ret=TRIGGER_READOUT; + } else if (g<0 && t<0 && rot<0) { + ret=AUTO_TIMING; + } + + // timingMode=ret; + + return ret; + +} + + + +int setConfigurationRegister(int d) { +#ifdef VERBOSE + printf("Setting configuration register to %x",d); +#endif + if (d>=0) { + bus_w(CONFIG_REG,d); + } +#ifdef VERBOSE + printf("configuration register is %x", bus_r(CONFIG_REG)); +#endif + return bus_r(CONFIG_REG); +} + +int setToT(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting ToT to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: ToT is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|TOT_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~TOT_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("ToT is %x\n", reg); +#endif + if (reg&TOT_ENABLE_BIT) + return 1; + else + return 0; +} + +int setContinousReadOut(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting Continous readout to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: Continous readout is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|CONT_RO_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~CONT_RO_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Continous readout is %x\n", reg); +#endif + if (reg&CONT_RO_ENABLE_BIT) + return 1; + else + return 0; +} + + +int startReceiver(int start) { + u_int32_t addr=CONFIG_REG; +#ifdef VERBOSE + if(start) + printf("Setting up detector to send to Receiver\n"); + else + printf("Setting up detector to send to CPU\n"); +#endif + int reg=bus_r(addr); + //for start recever, write 0 and for stop, write 1 + if (!start) + bus_w(CONFIG_REG,reg&(~GB10_NOT_CPU_BIT)); + else + bus_w(CONFIG_REG,reg|GB10_NOT_CPU_BIT); + + reg=bus_r(addr); +//#ifdef VERBOSE + printf("Config Reg %x\n", reg); +//#endif + int d =reg&GB10_NOT_CPU_BIT; + if(d!=0) d=1; + if(d!=start) + return OK; + else + return FAIL; +} + + +u_int64_t getDetectorNumber() { + char output[255],mac[255]=""; + u_int64_t res=0; + FILE* sysFile = popen("ifconfig eth0 | grep HWaddr | cut -d \" \" -f 11", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + //getting rid of ":" + char * pch; + pch = strtok (output,":"); + while (pch != NULL){ + strcat(mac,pch); + pch = strtok (NULL, ":"); + } + sscanf(mac,"%llx",&res); + return res; +} + +u_int32_t getFirmwareVersion() { + return bus_r(FPGA_VERSION_REG); +} + +u_int32_t getFirmwareSVNVersion(){ + return bus_r(FPGA_SVN_REG); +} + + +// for fpga test +u_int32_t testFpga(void) { + printf("Testing FPGA:\n"); + volatile u_int32_t val,addr,val2; + int result=OK,i; + //fixed pattern + val=bus_r(FIX_PATT_REG); + if (val==FIXED_PATT_VAL) { + printf("fixed pattern ok!! %08x\n",val); + } else { + printf("fixed pattern wrong!! %08x\n",val); + result=FAIL; + } + + //dummy register + addr = DUMMY_REG; + for(i=0;i<1000000;i++) + { + val=0x5A5A5A5A-i; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x5A5A5A5A-i) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of %x \n",i,val,0x5A5A5A5A-i); + result=FAIL; + } + val=(i+(i<<10)+(i<<20)); + bus_w(addr, val); + val2=bus_r(addr); + if (val2!=val) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! read %x instead of %x.\n",i,val2,val); + result=FAIL; + } + val=0x0F0F0F0F; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x0F0F0F0F) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0x0F0F0F0F \n",i,val); + result=FAIL; + } + val=0xF0F0F0F0; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0xF0F0F0F0) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0xF0F0F0F0 \n\n",i,val); + result=FAIL; + } + } + if(result==OK) + { + printf("----------------------------------------------------------------------------------------------"); + printf("\nATTEMPT 1000000: FPGA DUMMY REGISTER OK!!!\n"); + printf("----------------------------------------------------------------------------------------------"); + } + printf("\n"); + return result; +} + + +// for fpga test +u_int32_t testRAM(void) { + int result=OK; + + printf("TestRAM not implemented\n"); + +/* int i=0; + allocateRAM(); + // while(i<100000) { + memcpy(ram_values, values, dataBytes); + printf ("Testing RAM:\t%d: copied fifo %x to memory %x size %d\n",i++, (unsigned int)(values), (unsigned int)(ram_values), dataBytes); + // } + * +*/ + return result; +} + + +int getNModBoard() { +if(myDetectorType == JUNGFRAU) + return 1; +else + return 32;//nModX; +} + +int setNMod(int n) { + +/* printf("Writin ADC disable register %08x\n",n); */ +/* bus_w(ADC_LATCH_DISABLE_REG,n); */ + return getNMod(); +} + +int getNMod() { +/* u_int32_t reg; */ +/* int i; */ +/* reg=bus_r(ADC_LATCH_DISABLE_REG); */ + +/* printf("Read ADC disable register %08x\n",reg); */ +/* nModX=32; */ +/* for (i=0; i<32; i++) { */ +/* if (reg & (1<> 32; + vMSB=v64&(0xffffffff); + bus_w(aMSB,vMSB); + } + return get64BitReg(aLSB, aMSB); + +} + +int64_t get64BitReg(int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + vLSB=bus_r(aLSB); + vMSB=bus_r(aMSB); + v64=vMSB; + v64=(v64<<32) | vLSB; + + printf("reg64(%x,%x) %x %x %llx\n", aLSB, aMSB, vLSB, vMSB, v64); + + return v64; +} + +int64_t setFrames(int64_t value){ + return set64BitReg(value, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); +} + +int64_t getFrames(){ + /*printf("gf");*/ + return get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); +} + +int64_t setExposureTime(int64_t value){ + /* time is in ns */ + if (value!=-1) + value*=(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); + return set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t getExposureTime(){ + return get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t setGates(int64_t value){ + return set64BitReg(value, SET_GATES_LSB_REG, SET_GATES_MSB_REG); +} + +int64_t getGates(){ + return get64BitReg(GET_GATES_LSB_REG, GET_GATES_MSB_REG); +} + +int64_t setPeriod(int64_t value){ + /* time is in ns */ + if (value!=-1) { + // value*=(1E-9*CLK_FREQ); + value*=(1E-3*clkDivider[1]); + } + if (value%2==0) { + + printf("Adding one to period: was %08llx ", value); + value+=1; + printf("now is %08llx\n ", value); + + + } else + printf("Period already even is %08llx\n ", value); + + + return set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t getPeriod(){ + return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t setDelay(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-3*clkDivider[1]);//(1E-9*CLK_FREQ); + } + return set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t getDelay(){ + return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG)/(1E-3*clkDivider[0]);//(1E-9*CLK_FREQ); +} + +int64_t setTrains(int64_t value){ + return set64BitReg(value, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); +} + +int64_t getTrains(){ + return get64BitReg(GET_CYCLES_LSB_REG, GET_CYCLES_MSB_REG); +} + + +int64_t setProbes(int64_t value){ + return 0; +} + + +int64_t setProgress() { + + //????? eventually call after setting the registers + +return 0; + +} + + +int64_t getProgress() { + + + //should be done in firmware!!!! + + return 0; + +} + +int64_t getActualTime(){ + return get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getMeasurementTime(){ + int64_t v=get64BitReg(GET_MEASUREMENT_TIME_LSB_REG, GET_MEASUREMENT_TIME_MSB_REG); + // int64_t mask=0x8000000000000000; + // if (v & mask ) { + //#ifdef VERBOSE + // printf("no measurement time left\n"); + //#endif + // return -1E+9; + // } else + return v/(1E-9*CLK_FREQ); +} + +int64_t getFramesFromStart(){ + int64_t v=get64BitReg(FRAMES_FROM_START_LSB_REG, FRAMES_FROM_START_MSB_REG); + int64_t v1=get64BitReg(FRAMES_FROM_START_PG_LSB_REG, FRAMES_FROM_START_PG_MSB_REG); + + printf("Frames from start data streaming %lld\n",v); + printf("Frames from start run control %lld\n",v1); + + // int64_t mask=0x8000000000000000; + // if (v & mask ) { + //#ifdef VERBOSE + // printf("no measurement time left\n"); + //#endif + // return -1E+9; + // } else + return v; +} + + +ROI *setROI(int nroi,ROI* arg,int *retvalsize, int *ret) { + + if(myDetectorType == JUNGFRAU) + cprintf(RED,"ROI Not implemented for Jungfrau yet\n"); + return NULL; + + + ROI retval[MAX_ROIS]; + int i, ich; + adcDisableMask=0xfffffffff; /*warning: integer constant is too large for ‘long’ type,warning: large integer implicitly truncated to unsigned type*/ + + printf("Setting ROI\n"); + if (nroi>=0) { + if (nroi==0) { + adcDisableMask=0; + } else { + for (i=0; i=0 && ichMAX_ROIS) { + *retvalsize-=1; + break; + } + retval[*retvalsize-1].xmin=ich; + retval[*retvalsize-1].xmax=ich; + } else { + if ((adcDisableMask)&(1<<(ich-1))) { + *retvalsize+=1; + if (*retvalsize>MAX_ROIS) { + *retvalsize-=1; + break; + } + retval[*retvalsize-1].xmin=ich; + } + retval[*retvalsize-1].xmax=ich; + } + } + } + getDynamicRange(); + return retval;/*warning: function returns address of local variable*/ + +} + + +int loadImage(int index, short int ImageVals[]){ + + printf("loadImage Not implemented yet\n"); + + /* + u_int32_t address; + switch (index) { + case DARK_IMAGE : + address = DARK_IMAGE_REG; + break; + case GAIN_IMAGE : + address = GAIN_IMAGE_REG; + break; + } + volatile u_int16_t *ptr; + ptr=(u_int16_t*)(CSP0BASE+address*2); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,ImageVals[i]); +#endif + memcpy(ptr,ImageVals ,dataBytes); +#ifdef VERBOSE + printf("\nLoaded x%08x address with image of index %d\n",(unsigned int)(ptr),index); +#endif + */ + + return OK; +} + + + +int64_t getProbes(){ + return 0; +} + + +int setDACRegister(int idac, int val, int imod) { + u_int32_t addr, reg, mask; + int off; +#ifdef VERBOSE + if(val==-1) + printf("Getting dac register%d module %d\n",idac,imod); + else + printf("Setting dac register %d module %d to %d\n",idac,imod,val); +#endif + + switch(idac){ + case 0: + case 1: + case 2: + addr=MOD_DACS1_REG; + break; + case 3: + case 4: + case 5: + addr=MOD_DACS2_REG; + break; + case 6: + case 7: + addr=MOD_DACS3_REG; + break; + default: + printf("weird idac value %d\n",idac); + return -1; + break; + } + //saving only the msb + val=val>>2; + + off=(idac%3)*10; + mask=~((0x3ff)<=0 && val>off)&0x3ff; + //since we saved only the msb + val=val<<2; + + //val=(bus_r(addr)>>off)&0x3ff; + + +#ifdef VERBOSE + printf("Dac %d module %d register is %d\n\n",idac,imod,val); +#endif + return val; +} + + +int getTemperature(int tempSensor, int imod){ + int val; + imod=0;//ignoring more than 1 mod for now + int i,j,repeats=6; + u_int32_t tempVal=0; +#ifdef VERBOSE + char cTempSensor[2][100]={"ADCs/ASICs","VRs/FPGAs"}; + printf("Getting Temperature of module:%d for the %s for tempsensor:%d\n",imod,cTempSensor[tempSensor],tempSensor); +#endif + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + bus_w(TEMP_IN_REG,((T1_CLK_BIT)&~(T1_CS_BIT))|(T2_CLK_BIT));//high clk low cs + + for(i=0;i<20;i++) { + //repeats is number of register writes for delay + for(j=0;j>1);//fpga + } + } + + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + val=((int)tempVal)/4.0; + +#ifdef VERBOSE + printf("Temperature of module:%d for the %s is %.2fC\n",imod,cTempSensor[tempSensor],val); +#endif + return val; +} + + + +int initHighVoltage(int val, int imod){ + + + u_int32_t offw,codata; + u_int16_t valw, dacvalue; + int iru,i,ddx,csdx,cdx; + float alpha=0.55, fval=val; + + if (val>=0) { + + if (val<60) { + dacvalue=0; + val=60; + } else if (val>=200) { + dacvalue=0x1; + val=200; + } else { + dacvalue=1.+(200.-val)/alpha; + val=200.-(dacvalue-1)*alpha; + } + printf ("****************************** setting val %d, dacval %d\n",val, dacvalue); + offw=DAC_REG; + + ddx=8; csdx=10; cdx=9; + codata=((dacvalue)&0xff); + + + + + valw=0xffff; bus_w(offw,(valw)); // start point + valw=((valw&(~(0x1<>(7-i))&0x1)< 1 ) { + sum += *addr++; + count -= 2; + } + if( count > 0 ) sum += *addr; // Add left-over byte, if any + while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);// Fold 32-bit sum to 16 bits + checksum = (~sum)&0xffff; + + printf("IP checksum is 0x%lx\n",checksum); + + return checksum; +} + + + +#ifdef NEW_GBE_INTERFACE +int writeGbeReg(int ivar, uint32_t val, int addr, int interface) { +/* #define GBE_CTRL_WSTROBE 0 */ +/* #define GBE_CTRL_VAR_OFFSET 16 */ +/* #define GBE_CTRL_VAR_MASK 0XF */ +/* #define GBE_CTRL_RAMADDR_OFFSET 24 */ +/* #define GBE_CTRL_RAMADDR_MASK 0X3F */ +/* #define GBE_CTRL_INTERFACE 23 */ + uint32_t ctrl=((ivar&GBE_CTRL_VAR_MASK)<>32)&0xFFFFFFFF; + vals[IPCHECKSUM_ADDR]=checksum; + vals[GBE_DELAY_ADDR]=0; + vals[GBE_RESERVED1_ADDR]=sourceport; + vals[GBE_RESERVED2_ADDR]=interface; + vals[DETECTOR_MAC_L_ADDR]=(sourcemac)&0xFFFFFFFF; + vals[DETECTOR_MAC_H_ADDR]=(sourcemac>>32)&0xFFFFFFFF; + vals[DETECTOR_IP_ADDR]=sourceip; + + for (ivar=0; ivar>32)&0xFFFFFFFF);//rx_udpmacH_AReg_c + bus_w(RX_UDPMACL_AREG,(destmac)&0xFFFFFFFF);//rx_udpmacL_AReg_c + bus_w(DETECTORMACH_AREG,(sourcemac>>32)&0xFFFFFFFF);//detectormacH_AReg_c + bus_w(DETECTORMACL_AREG,(sourcemac)&0xFFFFFFFF);//detectormacL_AReg_c + bus_w(UDPPORTS_AREG,((sourceport&0xFFFF)<<16)+(destport&0xFFFF));//udpports_AReg_c + bus_w(IPCHKSUM_AREG,(checksum&0xFFFF));//ipchksum_AReg_c + + +#endif + + bus_w(CONTROL_REG,GB10_RESET_BIT); + sleep(1); + bus_w(CONTROL_REG,0); + usleep(10000); + bus_w(CONFIG_REG,conf | GB10_NOT_CPU_BIT); + printf("System status register is %08x\n",bus_r(SYSTEM_STATUS_REG)); + +return 0; //any value doesnt matter - dhanya + +} + + + + + + + + + + + +int configureMAC(uint32_t destip,uint64_t destmac,uint64_t sourcemac,int sourceip,int ival,uint32_t destport) { +//int configureMAC(int ipad,long long int macad,long long int detectormacad, int detipad, int ival, int udpport){ + + uint32_t sourceport = 0x7e9a; // 0xE185; + int interface=0; + int ngb; +volatile u_int32_t conf= bus_r(CONFIG_REG); + + + + + +#ifdef NEW_GBE_INTERFACE + ngb=2; + printf("--------- New XGB interface\n"); +#else + ngb=1; + printf("********* Old XGB interface\n"); +#endif + + for (interface=0; interface >((i)*2))==3) { *\/ */ +/* /\* i++; *\/ */ +/* /\* if (i>15) *\/ */ +/* /\* break; *\/ */ +/* /\* } *\/ */ +/* /\* if (i<16) { *\/ */ +/* bus_w16(DUMMY_REG,i); */ +/* } */ +/* val=*values; */ + + + // bus_w16(DUMMY_REG,0); // + for (i=0; i<16; i++) { + + + // bus_w16(DUMMY_REG,i); + // bus_r16(DUMMY_REG); +/* dum=(((u_int16_t*)(now_ptr))+i); */ +/* *dum=bus_r16(FIFO_DATA_REG); */ +/* a=bus_r16(FIFO_DATA_REG); */ + //dum=(((u_int32_t*)(now_ptr))+i); + + // a=*values;//bus_r(FIFO_DATA_REG); + // if ((adcDisableMask&(3<<(i*2)))==0) { + *((u_int32_t*)now_ptr)=*values;//bus_r(FIFO_DATA_REG); + + + if (i!=0 || ns!=0) { + a=0; + while (*((u_int32_t*)now_ptr)==*((u_int32_t*)(now_ptr)-1) && a++<10) { + + // printf("******************** %d: fifo %d: new %08x old %08x\n ",ns, i, *((u_int32_t*)now_ptr),*((u_int32_t*)(now_ptr)-1)); + *((u_int32_t*)now_ptr)=*values; + // printf("%d-",i); + + } + } + now_ptr+=4; + // } +/* while (((adcDisableMask&(3<<((i+1)*2)))>>((i+1)*2))==3) { */ +/* i++; */ +/* } */ + + // if (((adcDisableMask&(3<<((i+1)*2)))>>((i+1)*2))!=3) { + + bus_w16(DUMMY_REG,i+1); + // } + // *(((u_int16_t*)(now_ptr))+i)=bus_r16(FIFO_DATA_REG); + } + // bus_w16(DUMMY_REG,0); // +/* #ifdef TIMEDBG */ + +/* gettimeofday(&tss,NULL); */ +/* printf("read data loop = %ld usec\n",(tss.tv_usec) - (tse.tv_usec)); */ + +/* #endif */ +#ifdef VERBOSE + printf("*"); +#endif + return ram_values; +} + + + +u_int16_t* fifo_read_frame() +{ +#ifdef TIMEDBG + gettimeofday(&tsss,NULL); +#endif + + // u_int16_t *dum; + int ns=0; + now_ptr=(char*)ram_values; + while(ns>(ipos))&0x1; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibyte>(ipos*4))&0xf; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichan0) { + dynamicRange=16; + nSamples=dr/16; + bus_w(NSAMPLES_REG,nSamples); + } + getDynamicRange(); + allocateRAM(); + printf("Setting dataBytes to %d: dr %d; samples %d\n",dataBytes, dynamicRange, nSamples); + return getDynamicRange(); +} + + + + + + +int getDynamicRange() { + if(myDetectorType == JUNGFRAU){ + dynamicRange=16; + return dynamicRange; + } + + nSamples=bus_r(NSAMPLES_REG); + getChannels(); + dataBytes=nModX*N_CHIP*getChannels()*2; + return dynamicRange*bus_r(NSAMPLES_REG);//nSamples; +} + +int testBus() { + u_int32_t j; + u_int64_t i, n, nt; + // char cmd[100]; + u_int32_t val=0x0; + int ifail=OK; + // printf("%s\n",cmd); + // system(cmd); + i=0; + + n=1000000; + nt=n/100; + printf("testing bus %d times\n",(int)n); + while (i0) + storeInRAM=1; + else + storeInRAM=0; + return allocateRAM(); +} + +int getChannels() { + int nch=32; + int i; + for (i=0; i1) { + + clearRAM(); + ram_values=malloc(size); + // ram_values=realloc(ram_values,size)+2; + // if (ram_values) + // break; + // nSamples--; + //} + + if (ram_values) { + now_ptr=(char*)ram_values; + + //#ifdef VERBOSE + printf("ram allocated 0x%x of size %d to %x\n",(int)now_ptr,(unsigned int) size,(unsigned int)(now_ptr+size)); + //#endif + ram_size=size; + return OK; + } + + + printf("Fatal error: there must be a memory leak somewhere! You can't allocate even one frame!\n"); + return FAIL; + + + + +} + + +int writeADC(int addr, int val) { + + + u_int32_t valw,codata,csmask; + int i,cdx,ddx; + cdx=0; ddx=1; + csmask=0xfc; // 1111100 + + codata=val + (addr<< 8); + printf("***** ADC SPI WRITE TO REGISTER %04X value %04X\n",addr,val); + // start point + valw=0xff; + bus_w16(ADC_WRITE_REG,(valw)); + + //chip sel bar down + valw=((0xffffffff&(~csmask))); + bus_w16(ADC_WRITE_REG,valw); + + for (i=0;i<24;i++) { + //cldwn + valw=valw&(~(0x1<>(23-i))&0x1)<> 8); + // printf("%i: %i %i\n",a, frame[a],v); + avg[a] += ((double)frame[a])/(double)frames; + //if(frame[a] == 8191) + // printf("ch %i: %u\n",a,frame[a]); + } + // printf("********\n"); + numberFrames++; + } + + //no more data or no data + else { + if(getFrames()>-2) { + dataret=FAIL; + printf("no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + + } else { + dataret=FINISHED; + printf("acquisition successfully finished\n"); + + } + printf("dataret %d\n",dataret); + } + } + + + + //double nf = (double)numberFrames; + for(i =0; i < 1280; i++){ + adc = i / 256; + adcCh = (i - adc * 256) / 32; + Ch = i - adc * 256 - adcCh * 32; + adc--; + double v2 = avg[i]; + avg[i] = avg[i]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[i]; + printf("setting avg for channel %i(%i,%i,%i): %i (double= %f (%f))\t", i,adc,adcCh,Ch, v,avg[i],v2); + v=i*100; + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + + /*for(adc = 1; adc < 5; adc++){ + for(adcCh = 0; adcCh < 8; adcCh++){ + for(Ch=0 ; Ch < 32; Ch++){ + int channel = (adc+1) * 32 * 8 + adcCh * 32 + Ch; + double v2 = avg[channel]; + avg[channel] = avg[channel]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[channel]; + printf("setting avg for channel %i: %i (double= %f (%f))\t", channel, v,avg[channel],v2); + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + } + }*/ + + + + printf("frames: %i\n",numberFrames); + printf("corrected avg by: %f\n",(double)numberFrames/(double)frames); + + printf("restoring previous condition\n"); + setFrames(framesBefore); + setPeriod(periodBefore); + + printf("---------------------------\n"); + return 0; +} +uint64_t readPatternWord(int addr) { + uint64_t word=0; + int cntrl=0; + + if (addr>=MAX_PATTERN_LENGTH) + return -1; + + + printf("read %x\n",addr); + cntrl= (addr&APATTERN_MASK) << PATTERN_CTRL_ADDR_OFFSET; + bus_w(PATTERN_CNTRL_REG, cntrl); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl | (1<< PATTERN_CTRL_READ_BIT) ); + usleep(1000); + printf("reading\n"); + word=get64BitReg(PATTERN_OUT_LSB_REG,PATTERN_OUT_MSB_REG); + printf("read %llx\n", word); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl); + printf("done\n"); + + return word; +} + +uint64_t writePatternWord(int addr, uint64_t word) { + + + int cntrl=0; + if (addr>=MAX_PATTERN_LENGTH) + return -1; + + printf("write %x %llx\n",addr, word); + if (word!=-1){ + + set64BitReg(word,PATTERN_IN_REG_LSB,PATTERN_IN_REG_MSB); + + + cntrl= (addr&APATTERN_MASK) << PATTERN_CTRL_ADDR_OFFSET; + bus_w(PATTERN_CNTRL_REG, cntrl); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl | (1<< PATTERN_CTRL_WRITE_BIT) ); + usleep(1000); + bus_w(PATTERN_CNTRL_REG, cntrl); + return word; + } else + return readPatternWord(addr); +} +uint64_t writePatternIOControl(uint64_t word) { + if (word!=0xffffffffffffffff) { /*warning: integer constant is too large for ‘long’ type*/ + // printf("%llx %llx %lld",get64BitReg(PATTERN_IOCTRL_REG_LSB,PATTERN_IOCTRL_REG_MSB),word); + set64BitReg(word,PATTERN_IOCTRL_REG_LSB,PATTERN_IOCTRL_REG_MSB); + // printf("************ write IOCTRL (%x)\n",PATTERN_IOCTRL_REG_MSB); + } + return get64BitReg(PATTERN_IOCTRL_REG_LSB,PATTERN_IOCTRL_REG_MSB); + +} +uint64_t writePatternClkControl(uint64_t word) { + if (word!=0xffffffffffffffff) set64BitReg(word,PATTERN_IOCLKCTRL_REG_LSB,PATTERN_IOCLKCTRL_REG_MSB);/*warning: integer constant is too large for ‘long’ type*/ + return get64BitReg(PATTERN_IOCLKCTRL_REG_LSB,PATTERN_IOCLKCTRL_REG_MSB); + +} + +int setPatternLoop(int level, int *start, int *stop, int *n) { + int ret=OK; + int lval=0; + + int nreg; + int areg; + + switch (level ) { + case 0: + nreg=PATTERN_N_LOOP0_REG; + areg=PATTERN_LOOP0_AREG; + break; + case 1: + nreg=PATTERN_N_LOOP1_REG; + areg=PATTERN_LOOP1_AREG; + break; + case 2: + nreg=PATTERN_N_LOOP2_REG; + areg=PATTERN_LOOP2_AREG; + break; + case -1: + nreg=-1; + areg=PATTERN_LIMITS_AREG; + break; + default: + return FAIL; + } + + printf("level %d start %x stop %x nl %d\n",level, *start, *stop, *n); + if (nreg>=0) { + if ((*n)>=0) bus_w(nreg, *n); + printf ("n %d\n",*n); + *n=bus_r(nreg); + printf ("n %d\n",*n); + + } + + printf("level %d start %x stop %x nl %d\n",level, *start, *stop, *n); + lval=bus_r(areg); +/* printf("l=%x\n",bus_r16(areg)); */ +/* printf("m=%x\n",bus_r16_m(areg)); */ + + + + + + printf("lval %x\n",lval); + if (*start==-1) *start=(lval>> ASTART_OFFSET) & APATTERN_MASK; + printf("start %x\n",*start); + + + if (*stop==-1) *stop=(lval>> ASTOP_OFFSET) & APATTERN_MASK; + printf("stop %x\n",*stop); + + lval= ((*start & APATTERN_MASK) << ASTART_OFFSET) | ((*stop & APATTERN_MASK) << ASTOP_OFFSET); + printf("lval %x\n",lval); + + bus_w(areg,lval); + printf("lval %x\n",lval); + + + return ret; +} + + +int setPatternWaitAddress(int level, int addr) { + int reg; + + switch (level) { + case 0: + reg=PATTERN_WAIT0_AREG; + break; + case 1: + reg=PATTERN_WAIT1_AREG; + break; + case 2: + reg=PATTERN_WAIT2_AREG; + break; + default: + return -1; + }; + // printf("BEFORE *********PATTERN IOCTRL IS %llx (%x)\n",writePatternIOControl(-1), PATTERN_IOCTRL_REG_MSB); + + // printf ("%d addr %x (%x)\n",level,addr,reg); + if (addr>=0) bus_w(reg, addr); + // printf ("%d addr %x %x (%x) \n",level,addr, bus_r(reg), reg); + + // printf("AFTER *********PATTERN IOCTRL IS %llx (%x)\n",writePatternIOControl(-1), PATTERN_IOCTRL_REG_MSB); + + return bus_r(reg); +} + + +uint64_t setPatternWaitTime(int level, uint64_t t) { + int reglsb; + int regmsb; + + + switch (level) { + case 0: + reglsb=PATTERN_WAIT0_TIME_REG_LSB; + regmsb=PATTERN_WAIT0_TIME_REG_MSB; + break; + case 1: + reglsb=PATTERN_WAIT1_TIME_REG_LSB; + regmsb=PATTERN_WAIT1_TIME_REG_MSB; + break; + case 2: + reglsb=PATTERN_WAIT2_TIME_REG_LSB; + regmsb=PATTERN_WAIT2_TIME_REG_MSB; + break; + default: + return -1; + } + + + if (t>=0) set64BitReg(t,reglsb,regmsb); + return get64BitReg(reglsb,regmsb); + +} + + +void initDac(int dacnum) { + + + u_int32_t offw,codata; + u_int16_t valw; + int i,ddx,csdx,cdx; + + + + //setting int reference + offw=DAC_REG; + + + ddx=0; cdx=1; + csdx=dacnum/8+2; + + + printf("data bit=%d, clkbit=%d, csbit=%d",ddx,cdx,csdx); + codata=((((0x6)<<4)+((0xf))<<16)+((0x0<<4)&0xfff0)); /*warning: suggest parentheses around + or - inside shift*/ + + valw=0xffff; bus_w(offw,(valw)); // start point + valw=((valw&(~(0x1<>(24-i))&0x1)<>(24-i))&0x1)); + + + valw=((valw&(~(0x1<>16)&0xffff; + else + return retval&0xffff; + +} + + +int setDac(int dacnum,int dacvalue){ + + u_int32_t offw,codata; + u_int16_t valw; + int i,ddx,csdx,cdx; + + int dacch=0; + + if (dacvalue>=0) { + + //setting int reference + offw=DAC_REG; + + + ddx=0; cdx=1; + csdx=dacnum/8+2; + + dacch=dacnum%8; + + printf("data bit=%d, clkbit=%d, csbit=%d",ddx,cdx,csdx); + + //modified to power down single channels + + // codata=((((0x2)<<4)+((dacch)&0xf))<<16)+((dacvalue<<4)&0xfff0); + codata=((((0x3)<<4)+((dacch)&0xf))<<16)+((dacvalue<<4)&0xfff0); + valw=0xffff; bus_w(offw,(valw)); // start point + valw=((valw&(~(0x1<>(24-i))&0x1)<>(24-i))&0x1)); + + + valw=((valw&(~(0x1<>(24-i))&0x1)<>(24-i))&0x1)); + + + valw=((valw&(~(0x1< +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +int mapCSP0(void); + +u_int16_t bus_r16(u_int32_t offset); +u_int16_t bus_w16(u_int32_t offset, u_int16_t data);//aldos function +u_int32_t bus_w(u_int32_t offset, u_int32_t data); +u_int32_t bus_r(u_int32_t offset); + +int setPhaseShiftOnce(); +int phaseStep(int st); +int getPhase(); +int cleanFifo(); +int setDAQRegister(); + +u_int32_t putout(char *s, int modnum); +u_int32_t readin(int modnum); +u_int32_t setClockDivider(int d, int ic); +u_int32_t getClockDivider(int ic); + +void resetPLL(); +u_int32_t setPllReconfigReg(u_int32_t reg, u_int32_t val, int trig); +u_int32_t getPllReconfigReg(u_int32_t reg, int trig); + +u_int32_t setSetLength(int d); +u_int32_t getSetLength(); +u_int32_t setWaitStates(int d); +u_int32_t getWaitStates(); +u_int32_t setTotClockDivider(int d); +u_int32_t getTotClockDivider(); +u_int32_t setTotDutyCycle(int d); +u_int32_t getTotDutyCycle(); +u_int32_t setOversampling(int d); +u_int32_t adcPipeline(int d); + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode); +int getExtSignal(int d); + +u_int32_t setFPGASignal(int d, enum externalSignalFlag mode); +int getFPGASignal(int d); + +int setTiming(int t); + + +int setConfigurationRegister(int d); +int setToT(int d); +int setContinousReadOut(int d); +int startReceiver(int d); + +int setDACRegister(int idac, int val, int imod); +int getDacRegister(int dacnum); + + +int getTemperature(int tempSensor,int imod); +int initHighVoltage(int val,int imod); +int initConfGain(int isettings,int val,int imod); + +int setADC(int adc); +//int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int ival, int udpport); +int configureMAC(uint32_t destip,uint64_t destmac,uint64_t sourcemac,int detipad,int ival,uint32_t destport); +int getAdcConfigured(); + + +u_int64_t getDetectorNumber(); +u_int32_t getFirmwareVersion(); +u_int32_t getFirmwareSVNVersion(); + +int testFifos(void); +u_int32_t testFpga(void); +u_int32_t testRAM(void); +int testBus(void); +int setDigitalTestBit(int ival); + +int64_t set64BitReg(int64_t value, int aLSB, int aMSB); +int64_t get64BitReg(int aLSB, int aMSB); + +int64_t setFrames(int64_t value); +int64_t getFrames(); + +int64_t setExposureTime(int64_t value); +int64_t getExposureTime(); + +int64_t setGates(int64_t value); +int64_t getGates(); + +int64_t setDelay(int64_t value); +int64_t getDelay(); + +int64_t setPeriod(int64_t value); +int64_t getPeriod(); + +int64_t setTrains(int64_t value); +int64_t getTrains(); + +int64_t setProbes(int64_t value); +int64_t getProbes(); + +int64_t getProgress(); +int64_t setProgress(); + +int64_t getActualTime(); +int64_t getMeasurementTime(); +int64_t getFramesFromStart(); + +u_int32_t runBusy(void); +u_int32_t runState(void); +u_int32_t dataPresent(void); + + +int startStateMachine(); +int stopStateMachine(); +int startReadOut(); +u_int32_t fifoReset(void); +u_int32_t fifoReadCounter(int fifonum); +u_int32_t fifoReadStatus(); + + +u_int32_t fifo_full(void); + + + +u_int16_t* fifo_read_event(int ns); +u_int16_t* fifo_read_frame(); +u_int32_t* decode_data(int* datain); +//u_int32_t move_data(u_int64_t* datain, u_int64_t* dataout); +int setDynamicRange(int dr); +int getDynamicRange(); +int getNModBoard(); +int setNMod(int n); +int getNMod(); + +int setStoreInRAM(int b); +int allocateRAM(); + + +int writeADC(int addr, int val); +int prepareADC(); + + +int clearRAM(); + + +int setMaster(int f); +int setSynchronization(int s); + +int loadImage(int index, short int ImageVals[]); +int readCounterBlock(int startACQ, short int CounterVals[]); +int resetCounterBlock(int startACQ); + +int calibratePedestal(int frames); + +uint64_t writePatternWord(int addr, uint64_t word); +uint64_t writePatternIOControl(uint64_t word); +uint64_t writePatternClkControl(uint64_t word); +int setPatternLoop(int level, int *start, int *stop, int *n); +int setPatternWaitAddress(int level, int addr); +uint64_t setPatternWaitTime(int level, uint64_t t); + + +void initDac(int dacnum); +int setDac(int dacnum,int dacvalue); + +ROI *setROI(int nroi,ROI* arg,int *retvalsize, int *ret); +int getChannels(); + +/* + +u_int32_t setNBits(u_int32_t); +u_int32_t getNBits(); +*/ + +/* +//move to mcb_funcs? + +int readOutChan(int *val); +u_int32_t getModuleNumber(int modnum); +int testShiftIn(int imod); +int testShiftOut(int imod); +int testShiftStSel(int imod); +int testDataInOut(int num, int imod); +int testExtPulse(int imod); +int testExtPulseMux(int imod, int ow); +int testDataInOutMux(int imod, int ow, int num); +int testOutMux(int imod); +int testFpgaMux(int imod); +int calibration_sensor(int num, int *values, int *dacs) ; +int calibration_chip(int num, int *values, int *dacs); +*/ + + +#endif diff --git a/slsDetectorSoftware/jungfrauDetectorServer/gitInfo.txt b/slsDetectorSoftware/jungfrauDetectorServer/gitInfo.txt new file mode 100644 index 000000000..921890a70 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/gitInfo.txt @@ -0,0 +1,9 @@ +Path: slsDetectorsPackage/slsDetectorSoftware/moenchDetectorServer +URL: origin git@gitorious.psi.ch:sls_det_software/sls_detector_software.git/moenchDetectorServer +Repository Root: origin git@gitorious.psi.ch:sls_det_software/sls_detector_software.git +Repsitory UUID: 046a469b1e6582c4c55bd6eaeb4818b618d0a9a9 +Revision: 55 +Branch: separate_receiver +Last Changed Author: Maliakal_Dhanya +Last Changed Rev: 14 +Last Changed Date: 2014-06-03 12:26:45 +0200 diff --git a/slsDetectorSoftware/jungfrauDetectorServer/gitInfoMoench.h b/slsDetectorSoftware/jungfrauDetectorServer/gitInfoMoench.h new file mode 100644 index 000000000..270653967 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/gitInfoMoench.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "git@gitorious.psi.ch:sls_det_software/sls_detector_software.git/moenchDetectorServer" +//#define SVNREPPATH "" +#define SVNREPUUID "046a469b1e6582c4c55bd6eaeb4818b618d0a9a9" +//#define SVNREV 0x14 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "Maliakal_Dhanya" +#define SVNREV 0x14 +#define SVNDATE 0x20140603 +// diff --git a/slsDetectorSoftware/jungfrauDetectorServer/gitInfoMoenchTmp.h b/slsDetectorSoftware/jungfrauDetectorServer/gitInfoMoenchTmp.h new file mode 100644 index 000000000..58e48f497 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/gitInfoMoenchTmp.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "" +//#define SVNREPPATH "" +#define SVNREPUUID "" +//#define SVNREV "" +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "" +#define SVNREV "" +#define SVNDATE "" +// diff --git a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerTest b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerTest new file mode 100755 index 000000000..a4574f51f Binary files /dev/null and b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerTest differ diff --git a/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.0.3 b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.0.3 new file mode 100755 index 000000000..a4574f51f Binary files /dev/null and b/slsDetectorSoftware/jungfrauDetectorServer/jungfrauDetectorServerv2.0.3 differ diff --git a/slsDetectorSoftware/jungfrauDetectorServer/mcb_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/mcb_funcs.c new file mode 100755 index 000000000..edf99652a --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/mcb_funcs.c @@ -0,0 +1,2701 @@ +#ifdef MCB_FUNCS + +#include +#include +#include +#include +#include +#include "registers_m.h" + +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" + + +/* global variables */ +#undef DEBUG +#undef DEBUGOUT + +extern int nModX; +//extern int dataBytes; +extern int dynamicRange; +enum detectorSettings thisSettings; + +int sChan, sChip, sMod, sDac, sAdc; +const int allSelected=-2; +const int noneSelected=-1; + + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +int *detectorDacs=NULL; +int *detectorAdcs=NULL; +//int numberOfProbes; + +ROI rois[MAX_ROIS]; +int nROI=0; +extern enum detectorType myDetectorType; + +/** for jungfrau reinitializing macro later in server_funcs.c in initDetector*/ +extern int N_CHAN; +extern int N_CHIP; +extern int N_DAC; +extern int N_ADC; +extern int N_CHANS; + +extern int nChans; +extern int nChips; +extern int nDacs; +extern int nAdcs; + +int initDetector() { + + int imod; + // sls_detector_module *myModule; + int n=getNModBoard(); + nModX=n; + +#ifdef VERBOSE + printf("Board is for %d modules\n",n); +#endif + + if(myDetectorType == JUNGFRAU){ + N_CHAN=JUNGFRAU_NCHAN; + N_CHIP=JUNGFRAU_NCHIP; + N_DAC=JUNGFRAU_NDAC; + N_ADC=JUNGFRAU_NADC; + N_CHANS=JUNGFRAU_NCHANS; + + nChans=N_CHAN; + nChips=N_CHIP; + nDacs=N_DAC; + nAdcs=N_ADC; + } + + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorDacs=malloc(n*N_DAC*sizeof(int)); + detectorAdcs=malloc(n*N_ADC*sizeof(int)); + detectorChips=NULL; + detectorChans=NULL; + detectorAdcs=NULL; + if(myDetectorType != JUNGFRAU){ + detectorChips=malloc(n*N_CHIP*sizeof(int)); + detectorChans=malloc(n*N_CHIP*N_CHAN*sizeof(int)); + } + +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",(unsigned int)(detectorModules), (unsigned int)(detectorModules+n)); + printf("dacs from 0x%x to 0x%x\n",(unsigned int)(detectorDacs), (unsigned int)(detectorDacs+n*N_DAC)); + printf("adcs from 0x%x to 0x%x\n",(unsigned int)(detectorAdcs), (unsigned int)(detectorAdcs+n*N_ADC)); + if(myDetectorType != JUNGFRAU){ + printf("chips from 0x%x to 0x%x\n",(unsigned int)(detectorChips), (unsigned int)(detectorChips+n*N_CHIP)); + printf("chans from 0x%x to 0x%x\n",(unsigned int)(detectorChans), (unsigned int)(detectorChans+n*N_CHIP*N_CHAN)); + } +#endif + + + for (imod=0; imoddacs=detectorDacs+imod*N_DAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*N_ADC; + if(myDetectorType != JUNGFRAU){ + (detectorModules+imod)->chipregs=detectorChips+imod*N_CHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*N_CHIP*N_CHAN; + } + (detectorModules+imod)->ndac=N_DAC; + (detectorModules+imod)->nadc=N_ADC; + (detectorModules+imod)->nchip=N_CHIP; + (detectorModules+imod)->nchan=N_CHIP*N_CHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + + /* + setCSregister(ALLMOD); //commented out by dhanya + setSSregister(ALLMOD); + counterClear(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + */ + + /* initialize dynamic range etc. */ + /* dynamicRange=getDynamicRange(); //always 16 not required commented out + nModX=setNMod(-1);*/ + + // dynamicRange=32; + // initChip(0, 0,ALLMOD); + //nModX=n; + // + allocateRAM(); + + return OK; +} + + + + +int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) { + destChan->chan=srcChan->chan; + destChan->chip=srcChan->chip; + destChan->module=srcChan->module; + destChan->reg=srcChan->reg; + return OK; +} + + +int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip) { + + int ichan; + int ret=OK; + if ((srcChip->nchan)>(destChip->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + + destChip->nchan=srcChip->nchan; + destChip->reg=srcChip->reg; + destChip->chip=srcChip->chip; + destChip->module=srcChip->module; + for (ichan=0; ichan<(srcChip->nchan); ichan++) { + *((destChip->chanregs)+ichan)=*((srcChip->chanregs)+ichan); + } + return ret; +} + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { + + int ichip, idac, ichan, iadc; + + int ret=OK; + +#ifdef VERBOSE + printf("Copying module %x to module %x\n",(unsigned int)(srcMod),(unsigned int)(destMod)); +#endif + + if (srcMod->module>=0) { +#ifdef VERBOSE + printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); +#endif + destMod->module=srcMod->module; + } + if (srcMod->serialnumber>=0){ +/* #ifdef VERBOSE */ +/* printf("Copying module serial number %x to module serial number %x\n",srcMod->serialnumber,destMod->serialnumber); */ +/* #endif */ + destMod->serialnumber=srcMod->serialnumber; + } + if ((srcMod->nchip)>(destMod->nchip)) { + printf("Number of chip of source is larger than number of chips of destination\n"); + return FAIL; + } + if ((srcMod->nchan)>(destMod->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + if ((srcMod->ndac)>(destMod->ndac)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + if ((srcMod->nadc)>(destMod->nadc)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + +#ifdef VERBOSE + printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); + printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); + printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); + printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); + +#endif + + + + destMod->ndac=srcMod->ndac; + destMod->nadc=srcMod->nadc; + destMod->nchip=srcMod->nchip; + destMod->nchan=srcMod->nchan; + if (srcMod->reg>=0) + destMod->reg=srcMod->reg; +#ifdef VERBOSE + printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); +#endif + if (srcMod->gain>=0) + destMod->gain=srcMod->gain; + if (srcMod->offset>=0) + destMod->offset=srcMod->offset; + + // printf("copying gain and offset %f %f to %f %f\n",srcMod->gain,srcMod->offset,destMod->gain,destMod->offset); + + if(myDetectorType != JUNGFRAU){ + for (ichip=0; ichip<(srcMod->nchip); ichip++) { + if (*((srcMod->chipregs)+ichip)>=0) + *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); + } + for (ichan=0; ichan<(srcMod->nchan); ichan++) { + if (*((srcMod->chanregs)+ichan)>=0) + *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); + } + } + + for (idac=0; idac<(srcMod->ndac); idac++) { + if (*((srcMod->dacs)+idac)>=0) + *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } + + for (iadc=0; iadc<(srcMod->nadc); iadc++) { + if (*((srcMod->adcs)+iadc)>=0) + *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); + } + + return ret; +} + + + +/* Register commands */ + + +/* int clearDACSregister(int imod) { */ + +/* putout("1111111111111111",imod);//reset */ +/* putout("1111111111111110",imod);//cs down */ + +/* /\* commented out by dhanya */ +/* putout("0000000001000000",imod); */ +/* putout("0000000101000000",imod); */ +/* putout("0000000101000000",imod); */ +/* putout("0000000001000000",imod); */ +/* *\/ */ +/* #ifdef DEBUG */ +/* fprintf(stdout, "Clearing DAC shiftregister\n"); */ +/* #endif */ +/* // sDac=0; */ +/* sMod=imod; */ +/* if (imod==ALLMOD) */ +/* sMod=allSelected; */ +/* return OK; */ +/* } */ + +/* int nextDAC(int imod) { */ + +/* putout("1111111111111011",imod);//cs up */ +/* putout("1111111111111001",imod);//clk down */ +/* putout("1111111111111111",imod);//reset */ + +/* /\*commented out by dhanya */ +/* putout("0000000001000000",imod); */ +/* putout("0000000001001000",imod); */ +/* putout("0000000001000000",imod); */ +/* *\/ */ +/* #ifdef DEBUG */ +/* fprintf(stdout, "Next DAC\n"); */ +/* #endif */ +/* // sDac++; */ +/* sMod=imod; */ +/* if (imod==ALLMOD) */ +/* sMod=allSelected; */ +/* return OK; */ +/* } */ + + +int clearCSregister(int imod) { + + putout("0000000001000000",imod); + putout("0000100001000000",imod); + putout("0000100001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Clearing CS shiftregister\n"); +#endif + /* + sChan=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + */ + sChip=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + //putout("0000000000000000",imod); + return 0; +} + +int setCSregister(int imod){ + + putout("0000000001000000",imod); + putout("0001000001000000",imod); + putout("0001000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Setting CS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChip=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextChip(int imod){ + + putout("0000000001000000",imod); + putout("0010000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Next Chip\n"); +#endif + sChip++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int firstChip(int imod){ + + putout("0100000001000000",imod); + putout("0110000001000000",imod); + putout("0100000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "First Chip\n"); +#endif + sChip=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int clearSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0000111000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Clearing SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int setSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0001011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Setting SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextStrip(int imod){ + putout("0000011000000000",imod); + putout("0010011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"|-"); +#endif + sChan++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int selChannel(const int strip,int imod) { + int istrip; + clearSSregister(imod); + nextStrip(imod); + for (istrip=0; istrip=0 && imod=0) */ +/* initDAC(ind,val, imod); */ + +/* if (imod>=0 && imodgain,(detectorModules+imod)->offset); */ +/* #endif */ +/* if ((detectorModules+imod)->gain>0) */ +/* myg=(detectorModules+imod)->gain; */ +/* else { */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myg=g[thisSettings]; */ +/* // else */ +/* //myg=-1; */ +/* } */ + +/* if ((detectorModules+imod)->offset>0) */ +/* myo=(detectorModules+imod)->offset; */ +/* else { */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myo=o[thisSettings]; */ +/* // else */ +/* //myo=-1; */ +/* } */ + +/* if (myg>0 && myo>0) { */ +/* //ethr=(myo-detectorDacs[VTHRESH+imod*N_DAC])*1000/myg; */ + +/* ethr=(myo-setDACRegister(VDAC0,-1,imod))*1000/myg;//edited by dhanya */ +/* // else */ +/* // ethr=-1; */ + +/* } */ +/* #ifdef VERBOSE */ +/* //printf("module=%d gain=%f, offset=%f, dacu=%f\n",imod, myg, myo, detectorDacs[VTHRESH+imod*N_DAC]); */ +/* printf("module=%d gain=%f, offset=%f, dacu=%d\n",imod, myg, myo,(int)(setDACRegister(VDAC0,-1,imod)));//edited by dhanya */ +/* printf("Threshold energy of module %d is %d eV\n", imod, ethr); */ +/* #endif */ + +/* if (imod==0) */ +/* ret=ethr; */ +/* else { */ +/* if (ethr>(ret+100) || ethr<(ret-100)) */ +/* return FAIL; */ +/* } */ +/* } */ +/* } */ +/* return ret; */ +/* } */ + +/* int setThresholdEnergy(int ethr) { */ +/* double g[3]=DEFAULTGAIN; */ +/* double o[3]=DEFAULTOFFSET; */ +/* double myg=-1, myo=-1; */ +/* int dacu; */ +/* int imod; */ +/* int ret=ethr; */ + +/* setSettings(GET_SETTINGS,-1);//-1 added by dhanya */ +/* if (thisSettings>=0 || thisSettings<3){ */ +/* myg=g[thisSettings]; */ +/* myo=o[thisSettings]; */ +/* } */ +/* for (imod=0; imodgain>0) */ +/* myg=(detectorModules+imod)->gain; */ +/* else */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myg=g[thisSettings]; */ +/* else */ +/* myg=-1; */ +/* if ((detectorModules+imod)->offset>0) */ +/* myo=(detectorModules+imod)->offset; */ +/* else */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myo=o[thisSettings]; */ +/* else */ +/* myo=-1; */ +/* } else { */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myo=o[thisSettings]; */ +/* else */ +/* myo=-1; */ +/* if (thisSettings>=0 && thisSettings<3) */ +/* myg=g[thisSettings]; */ +/* else */ +/* myg=-1; */ +/* } */ +/* if (myg>0 && myo>0) { */ +/* dacu=myo-myg*((double)ethr)/1000.; */ +/* #ifdef VERBOSE */ +/* printf("module %d (%x): gain %f, off %f, energy %d eV, dac %d\n",imod,(unsigned int)((detectorModules+imod)),(detectorModules+imod)->gain,(detectorModules+imod)->offset, ethr,dacu); */ +/* #endif */ +/* } else { */ +/* dacu=ethr; */ +/* #ifdef VERBOSE */ +/* printf("could not set threshold energy for module %d, settings %d (offset is %f; gain is %f)\n",imod,thisSettings,myo,myg); */ +/* #endif */ +/* } */ +/* initDACbyIndexDACU(VDAC0, dacu, imod); ///needs to be fixed dhanya */ +/* } */ +/* return ret; */ +/* } */ + + + +/* int getDACbyIndexDACU(int ind, int imod) { */ +/* /\* */ +/* if (detectorDacs) { */ +/* if (imodndac) */ +/* return (detectorDacs[ind+imod*N_DAC]); */ +/* } */ +/* return FAIL; */ +/* *\/ */ +/* return setDACRegister(ind, -1, imod); */ +/* } */ + + +/* int initDAC(int dac_addr, int value, int imod) { */ +/* // int i; */ +/* #ifdef VERBOSE */ +/* printf("Programming dac %d with value %d\n", dac_addr, value); */ +/* #endif */ +/* clearDACSregister(imod); */ +/* program_one_dac(dac_addr,value,imod); */ +/* nextDAC(imod); */ +/* clearDACSregister(imod); */ + +/* return 0; */ +/* } */ + +int getTemperatureByModule(int tempSensor, int imod) +{ + int im; + //for the particular module + if (imod>=0 && imod=0 && imod=0 && imod=0) { */ +/* #ifdef VERBOSE */ +/* fprintf(stdout, "voltage %d\n", *(v+iaddr)); */ +/* #endif */ +/* program_one_dac(iaddr, *(v+iaddr),imod); */ +/* } */ +/* nextDAC(imod); */ +/* } */ + + +/* clearDACSregister(imod); */ + +/* return 0; */ + +/* } */ + + + + +int setSettings(int i, int imod) { +#ifdef VERBOSE + if(i==-1) + printf("\nReading settings of detector...\n"); + else + printf("\ninside set settings wit settings=%d...\n",i); +#endif + int isett=-1,val=-1,retval=-1; + enum conf_gain { + dynamic = 0x0f00, //dynamic + dynamichighgain0 = 0x0f01, //dynamichighgain0 + fixgain1 = 0x0f02, //fixgain1 + fixgain2 = 0x0f06, //fixgain2 + forceswitchgain1 = 0x1f00, //forceswitchgain1 + forceswitchgain2 = 0x3f00 //forceswitchgain2 + }; + + //determine conf value to write + if(i!=GET_SETTINGS){ + switch(i){ + case DYNAMICGAIN: val = dynamic;break; + case DYNAMICHG0: val = dynamichighgain0;break; + case FIXGAIN1: val = fixgain1;break; + case FIXGAIN2: val = fixgain2;break; + case FORCESWITCHG1: val = forceswitchgain1;break; + case FORCESWITCHG2: val = forceswitchgain2;break; + default: + printf("Error: This settings is not defined for this detector %d\n",i); + return GET_SETTINGS; + } + } + + retval=initConfGainByModule(i,val,imod); + + switch(retval){ + case dynamic: isett=DYNAMICGAIN; break; + case dynamichighgain0: isett=DYNAMICHG0; break; + case fixgain1: isett=FIXGAIN1; break; + case fixgain2: isett=FIXGAIN2; break; + case forceswitchgain1: isett=FORCESWITCHG1; break; + case forceswitchgain2: isett=FORCESWITCHG2; break; + default: + isett=UNDEFINED; + printf("Error:Wrong settings read out from Gain Reg 0x%x\n",retval); + break; + } + + thisSettings=isett; +//#ifdef VERBOSE + printf("detector settings are %d\n",thisSettings); +//#endif + return thisSettings; +} + + + + +/* Initialization*/ + +int initChannelbyNumber(sls_detector_channel myChan) {printf("in init channel by number\n"); + int reg=myChan.reg; + int ft=reg & TRIM_DR; + int cae=(reg>>(NTRIMBITS))&1; + int ae=(reg>>(NTRIMBITS+1))&1; + int coe=(reg>>(NTRIMBITS+2))&1; + int ocoe=(reg>>(NTRIMBITS+3))&1; + int counts=(reg>>(NTRIMBITS+4)); +#ifdef VERBOSE + printf("Initializing channel %d chip %d module %d reg %x\n",myChan.chan,myChan.chip,myChan.module, reg); + printf("trim %d, cae %d, ae %d, coe %d, ocoe %d, counts %d\n",ft, cae, ae, coe, ocoe, counts); +#endif + + if (myChan.chip<0) + setCSregister(myChan.module); + else + selChip(myChan.chip,myChan.module); + + if (myChan.chan<0) + setSSregister(myChan.module); + else + selChannel(myChan.chan,myChan.module); + + initChannel(ft,cae,ae, coe, ocoe, counts,myChan.module); + + setDynamicRange(dynamicRange); + + setCSregister(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + + return myChan.reg; + +} + +int getChannelbyNumber(sls_detector_channel* myChan) { + int imod, ichip, ichan; + imod=myChan->module; + ichip=myChan->chip; + ichan=myChan->chan; + + if (detectorChans) { + if (imod=0) { + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + myChan->reg=detectorChans[imod*N_CHAN*N_CHIP+ichip*N_CHAN+ichan]; + return OK; + } + } + return FAIL; + +} + +int getTrimbit(int imod, int ichip, int ichan) { + if (detectorChans) { + if (imod=0) + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + return (detectorChans[imod*N_CHAN*N_CHIP+ichip*N_CHAN+ichan] & TRIM_DR); + } + + return -1; +} + +int initChannel(int ft,int cae, int ae, int coe, int ocoe, int counts, int imod){ + + int ibit, bit, i, im, ichip, ichan; + int chanmi, chanma, chipmi, chipma, modmi, modma; + + + + sMod=imod; + // printf("initializing module %d\n",sMod); + if (imod==ALLMOD) { + sMod=allSelected; + + // printf("initializing all modules\n"); + } + + if (sChan==allSelected) { + // printf("initializing all channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=N_CHAN; + } else if (sChan==noneSelected || sChan>N_CHAN || sChan<0) { + // printf("initializing no channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=-1; + } else { + // printf("initializing channel %d ft=%d coe=%d\n",sChan, ft,coe); + chanmi=sChan; + chanma=sChan+1; + } + + if (sChip==allSelected) { + // printf("initializing all chips\n"); + chipmi=0; + chipma=N_CHIP; + } else if (sChip==noneSelected || sChip>N_CHIP || sChip<0) { + // printf("initializing no chips\n"); + chipmi=0; + chipma=-1; + } else { + // printf("initializing chip %d\n",sChip); + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + return 1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChans) { + for (im=modmi; im63 || ft<0) { + fprintf(stdout,"Fine Threshold is %d while should be between 0 and 63!",ft); + return 1; + } + /*cal_enable*/ + if (cae) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + } + /*n_an_enable*/ + if (ae) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } else { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } + /*trb5*/ + ibit=5; + bit=ft & (1<>1; + int nchan, ichan; + int ft, cae, ae, coe, ocoe, counts, chanreg; + + + + nchan=myChip.nchan; + if (ichip<0) + setCSregister(imod); + else + selChip(ichip,imod); + + clearSSregister(imod); + for (ichan=0; ichan>(NTRIMBITS+1))&1; + ae=(chanreg>>(NTRIMBITS+2))&1; + coe=((chanreg)>>(NTRIMBITS+3))&1; + ocoe=((chanreg)>>(NTRIMBITS+4))&1; + counts=((chanreg)>>(NTRIMBITS+5)); + nextStrip(imod); + initChannel(ft,cae,ae, coe, ocoe, counts,imod); + } + initChip(obe,ow,imod); + return myChip.reg; + +} + +int getChipbyNumber(sls_detector_chip* myChip){ + int imod, ichip; + imod=myChip->module; + ichip=myChip->chip; + + if (detectorChips) { + if (imodnchip) { + myChip->reg=detectorChips[ichip+imod*N_CHIP]; + myChip->nchan=N_CHAN; + myChip->chanregs=detectorChans+imod*N_CHAN*N_CHIP+ichip*N_CHIP; + return OK; + } + } + return FAIL; + +} + + + +int initChip(int obe, int ow,int imod){ + int i; + int im, ichip; + int chipmi, chipma, modmi, modma; + /* switch (ow) { + case 0:; + case 1: + setDynamicRange(32); + break; + case 2: + setDynamicRange(16); + break; + case 3: + setDynamicRange(8); + break; + case 4: + setDynamicRange(4); + break; + case 5: + setDynamicRange(1); + break; + default: + setDynamicRange(32); + break; + } + */ + +#ifdef DEBUGOUT + printf("Initializing chip\n"); +#endif + putout("0000000000000000",imod); +#ifdef DEBUGOUT + printf("Output mode= %d\n", ow); +#endif + + /* clearing shift in register */ + for (i=0; i<10; i++) + putout("0000100000000000",imod); + putout("0000000000000000",imod); + + if (ow>0) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + for (i=0; i<(OUTMUX_OFFSET-1); i++) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>1) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>2) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>3) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>4) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + } +#ifdef DEBUGOUT + printf("Output buffer enable= %d\n", obe); +#endif + if (obe) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + /*}*/ + putout("0000000000000000",imod); + + + + + + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + + + if (sChip==allSelected) { + chipmi=0; + chipma=N_CHIP; + } else if (sChip==noneSelected || sChip>N_CHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imN_CHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imnModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorModules) { + for (im=modmi; imreg)=cm; +#ifdef VERBOSE + printf("imod=%d reg=%d (%x)\n",im,(detectorModules+im)->reg,(unsigned int)((detectorModules+im))); +#endif + } + } + return 0; +} + +int initModulebyNumber(sls_detector_module myMod) { + + printf("\ninside initmoduleynumberrrr..\n"); + printf("000\n"); + int nchip,nchan;//int ichip, nchip, ichan, nchan; + int im, modmi,modma; + // int ft, cae, ae, coe, ocoe, counts, chanreg; + int imod; + // int obe; + // int ow; + /* int v[N_DAC];*/ + int retval =-1, idac; + + + nchip=myMod.nchip; + nchan=(myMod.nchan)/nchip; + + imod=myMod.module; + sMod=imod; + + if (sMod==ALLMOD) + sMod=allSelected; + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {// (sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + printf("222\n"); + /* + for (idac=0; idacmodule; +#ifdef VERBOSE + printf("Getting module %d\n",imod); +#endif + if (detectorModules) { + copyModule(myMod,detectorModules+imod); + ; + } else + return FAIL; + + return OK; +} + +/* To chips */ +int clearCounter(int imod){ + int i; +#ifdef DEBUG + printf("Clearing counter with contclear\n"); +#endif + putout("0000000000000000",imod); + for (i=0; i<10; i++) + putout("0000000000010000",imod); + putout("0000000000000000",imod); + + return 0; +} + +int clearOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Clearing output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0000110000000000",imod); + putout("0000010000000000",imod); + return 0; +} +int setOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Setting output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0001010000000000",imod); + putout("0000010000000000",imod); + return 0; +} + + +int extPulse(int ncal, int imod) { + int ical; +#ifdef DEBUG + printf("Giving a clock pulse to the counter\n"); +#endif + for (ical=0; ical0 && i%2==0) { + printf("Shift in: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<0 && (dum & (1<0) { + printf("Shift out: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, (dum &1<0 && i%2==0) { + printf("Shift stsel: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<> 1; + + + putout("0000000000000000",ALLMOD); + putout("0010000000000000",ALLMOD); //change mux setting + putout("0000000000000000",ALLMOD); + } + + printf("Test FpgaMux module %d : %d errors\n", imod,result); + if (result) + return 1; + else + return 0; +} + + + + + + + + + +int calibration_sensor(int num, int *v, int *dacs) { + int ich, ichip, imod; + int val[10]; + + + printf("calibrating sensor..."); + for (imod=0; imod=0){ */ + +/* //clear rois */ +/* for(i=0;i=0) && (adc<=4)); */ +/* else { */ +/* printf("warning:adc value greater than 5. deleting roi\n"); */ +/* adc=-1; */ +/* } */ +/* } */ +/* } */ + + +/* //set rois for just 1 adc - take only 1st roi */ +/* if(adc!=-1){ */ +/* rois[0].xmin=adc*(GOTTHARDNCHAN*NCHIPS_PER_ADC); */ +/* rois[0].xmax=(adc+1)*(GOTTHARDNCHAN*NCHIPS_PER_ADC)-1; */ +/* rois[0].ymin=-1; */ +/* rois[0].ymax=-1; */ +/* nROI = 1; */ +/* }else */ +/* nROI = 0; */ + +/* if((arg[0].xmin!=rois[0].xmin)||(arg[0].xmax!=rois[0].xmax)||(arg[0].ymin!=rois[0].ymin)||(arg[0].ymax!=rois[0].ymax)) */ +/* *ret=FAIL; */ +/* if(n!=nROI) */ +/* *ret=FAIL; */ + +/* //set adc of interest */ +/* setADC(adc); */ +/* } */ + +/* //#ifdef VERBOSE */ +/* printf("Rois:\n"); */ +/* for( i=0;i +#include "communication_funcs.h" +#include "server_funcs.h" +#include + + + +extern int sockfd; +extern int phase_shift; + + + +void error(char *msg) +{ + perror(msg); +} + +int main(int argc, char *argv[]) +{ + int portno, b; + char cmd[500]; + int retval=OK; + int sd, fd; + int iarg; + int checkType = 1; + + + for(iarg=1; iarg 2) && (!strcasecmp(argv[2],"stopserver"))){ + portno = DEFAULT_PORTNO+1; + if ( sscanf(argv[1],"%d",&portno) ==0) { + printf("could not open stop server: unknown port\n"); + return 1; + } + b=0; + printf("\n\nStop Server\nOpening stop server on port %d\n",portno); + checkType=0; + + } + + //control server + else { + portno = DEFAULT_PORTNO; + if(checkType) + sprintf(cmd,"%s %d stopserver &",argv[0],DEFAULT_PORTNO+1); + else + sprintf(cmd,"%s %d stopserver -test with_gotthard &",argv[0],DEFAULT_PORTNO+1); + printf("\n\nControl Server\nOpening control server on port %d\n",portno ); + + //printf("\n\ncmd:%s\n",cmd); + system(cmd); + b=1; + checkType=1; + + } + + + + + + init_detector(b, checkType); + + + sd=bindSocket(portno); + sockfd=sd; + if (getServerError(sd)) { + printf("server error!\n"); + return -1; + } + + /* assign function table */ + function_table(); +#ifdef VERBOSE + printf("function table assigned \n"); +#endif + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Waiting for client call\n"); +#endif + fd=acceptConnection(sockfd); +#ifdef VERY_VERBOSE + printf("Conenction accepted\n"); +#endif + retval=decode_function(fd); +#ifdef VERY_VERBOSE + printf("function executed\n"); +#endif + closeConnection(fd); +#ifdef VERY_VERBOSE + printf("connection closed\n"); +#endif + } + + exitServer(sockfd); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/jungfrauDetectorServer/server_defs.h b/slsDetectorSoftware/jungfrauDetectorServer/server_defs.h new file mode 100755 index 000000000..6a1f8eb23 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/server_defs.h @@ -0,0 +1,69 @@ +#ifndef SERVER_DEFS_H +#define SERVER_DEFS_H + +#include "sls_detector_defs.h" + +#include + + +// Hardware definitions +#define NMAXMODY 1 +#define NMAXMOD (NMAXMODX*NMAXMODY) + +#define NCHAN 32 +#define NCHIP 1 +#define NADC 1 +#define NDAC 16 +#define NMAXMODX 1 +#define NCHANS (NCHAN*NCHIP*NMAXMOD) +#define NDACS (NDAC*NMAXMOD) + +#define JUNGFRAU_NCHAN (256*256) +#define JUNGFRAU_NCHIP 8 +#define JUNGFRAU_NADC 0 +#define JUNGFRAU_NDAC 16 +#define JUNGFRAU_NCHANS (JUNGFRAU_NCHAN*JUNGFRAU_NCHIP*NMAXMOD) + + + +/**when moench readout tested with gotthard module*/ +#define GOTTHARDNCHAN 128 +#define GOTTHARDNCHIP 10 + + +#define NTRIMBITS 6 +#define NCOUNTBITS 24 + +#define NCHIPS_PER_ADC 2 + +//#define TRIM_DR ((2**NTRIMBITS)-1) +//#define COUNT_DR ((2**NCOUNTBITS)-1) +#define TRIM_DR (((int)pow(2,NTRIMBITS))-1) +#define COUNT_DR (((int)pow(2,NCOUNTBITS))-1) + + +#define ALLMOD 0xffff +#define ALLFIFO 0xffff + +#define GOTTHARD_ADCSYNC_VAL 0x32214 +#define ADCSYNC_VAL 0x02111 +#define TOKEN_RESTART_DELAY 0x88000000 +#define TOKEN_RESTART_DELAY_ROI 0x1b000000 +#define TOKEN_TIMING_REV1 0x1f16 +#define TOKEN_TIMING_REV2 0x1f0f + +#define DEFAULT_PHASE_SHIFT 0 // 120 +#define DEFAULT_IP_PACKETSIZE 0x0522 +#define DEFAULT_UDP_PACKETSIZE 0x050E +#define ADC1_IP_PACKETSIZE 256*2+14+20 +#define ADC1_UDP_PACKETSIZE 256*2+4+8+2 + +#ifdef VIRTUAL +#define DEBUGOUT +#endif + +#define CLK_FREQ 156.25E+6 +#define ADC_CLK_FREQ 32E+6 + + +#endif diff --git a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c new file mode 100755 index 000000000..e60cb1285 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.c @@ -0,0 +1,3503 @@ +#include "sls_detector_defs.h" +#include "sls_receiver_defs.h" +#include "server_funcs.h" +#include "server_defs.h" +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers_m.h" +#include "gitInfoMoench.h" + +#define FIFO_DATA_REG_OFF 0x50<<11 +// Global variables + + +int (*flist[256])(int); + + +//defined in the detector specific file +/* #ifdef MYTHEND */ +/* const enum detectorType myDetectorType=MYTHEN; */ +/* #elif GOTTHARDD */ +/* const enum detectorType myDetectorType=GOTTHARD; */ +/* #elif EIGERD */ +/* const enum detectorType myDetectorType=EIGER; */ +/* #elif PICASSOD */ +/* const enum detectorType myDetectorType=PICASSO; */ +/* #elif MOENCHD */ +/* const enum detectorType myDetectorType=MOENCH; */ +/* #else */ +enum detectorType myDetectorType=GENERIC; +/* #endif */ + + +extern int nModX; +extern int nModY; +extern int dataBytes; +extern int nSamples; +extern int dynamicRange; +extern int storeInRAM; + +extern int lockStatus; +extern char lastClientIP[INET_ADDRSTRLEN]; +extern char thisClientIP[INET_ADDRSTRLEN]; +extern int differentClients; + +/* global variables for optimized readout */ +extern unsigned int *ram_values; +char *dataretval=NULL; +int nframes, iframes, dataret; +char mess[MAX_STR_LENGTH]; + +int digitalTestBit = 0; + +extern int withGotthard; + + +int adcvpp=0x4; + +/** for jungfrau reinitializing macro later */ +int N_CHAN=NCHAN; +int N_CHIP=NCHIP; +int N_DAC=NDAC; +int N_ADC=NADC; +int N_CHANS=NCHANS; + + +int init_detector(int b, int checkType) { + + int i; + if (mapCSP0()==FAIL) { printf("Could not map memory\n"); + exit(1); + } + + //print version + printf("v: 0x%x\n",bus_r(FPGA_VERSION_REG)); + printf("fp: 0x%x\n",bus_r(FIX_PATT_REG)); + + //checktype + if (checkType) { + printf("Bus test... (checktype is %d; b is %d)",checkType,b ); + for (i=0; i<1000000; i++) { + bus_w(SET_DELAY_LSB_REG, i*100); + bus_r(FPGA_VERSION_REG); + if (i*100!=bus_r(SET_DELAY_LSB_REG)) + printf("ERROR: wrote 0x%x, read 0x%x\n",i*100,bus_r(SET_DELAY_LSB_REG)); + } + printf("Finished\n"); + }else + printf("(checktype is %d; b is %d)",checkType,b ); + + + //confirm the detector type + switch ((bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>>DETECTOR_TYPE_OFFSET) { + case MOENCH03_MODULE_ID: + myDetectorType=MOENCH; + printf("This is a MOENCH03 module %d\n",MOENCH); + break; + + case JUNGFRAU_MODULE_ID: + myDetectorType=JUNGFRAU; + printf("This is a Jungfrau module %d\n", JUNGFRAU); + break; + + case JUNGFRAU_CTB_ID: + myDetectorType=JUNGFRAUCTB; + printf("This is a Jungfrau CTB %d\n", JUNGFRAUCTB); + break; + + default: + myDetectorType=GENERIC; + printf("Unknown detector type %02x\n",(bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>>DETECTOR_TYPE_OFFSET); + break; + + } + printf("Detector type is %d\n", myDetectorType); + + + //control server only-- + if (b) { + resetPLL(); + bus_w16(CONTROL_REG, SYNC_RESET); + bus_w16(CONTROL_REG, 0); + bus_w16(CONTROL_REG, GB10_RESET_BIT); + bus_w16(CONTROL_REG, 0); + +#ifdef MCB_FUNCS + printf("\nBoard Revision:0x%x\n",(bus_r(PCB_REV_REG)&BOARD_REVISION_MASK)); + if(myDetectorType == JUNGFRAU) + initDetector(); /*allocating detectorModules, detectorsDacs etc for "settings", also does allocate RAM*/ + dataBytes=NMAXMOD*N_CHIP*N_CHAN*2; /**Nchip and Nchan real values get assigned in initDetector()*/ + printf("Initializing Detector\n"); + //bus_w16(CONTROL_REG, SYNC_RESET); // reset registers +#endif + + // testFpga(); + // testRAM(); + // printf("ADC_SYNC_REG:%x\n",bus_r(ADC_SYNC_REG)); + //moench specific + // setPhaseShiftOnce(); + /*some registers set, which is in common with jungfrau, please check */ + prepareADC(); + //setADC(-1); //already does setdaqreg and clean fifo + // setSettings(GET_SETTINGS,-1); + /*some registers set, which is in common with jungfrau, please check */ + initDac(0); initDac(8); //initializes the two dacs + + if(myDetectorType==JUNGFRAU){ + /** for jungfrau reinitializing macro */ + N_CHAN=JUNGFRAU_NCHAN; + N_CHIP=JUNGFRAU_NCHIP; + N_DAC=JUNGFRAU_NDAC; + N_ADC=JUNGFRAU_NADC; + N_CHANS=JUNGFRAU_NCHANS; + + + //set dacs + int retval = -1; + int dacvalues[14][2]={ + {0, 1250}, //vout_cm + {10, 1053}, //vin_com + {1, 600}, //vb_sda + {11, 1000}, //vb_colbuf + {2, 3000}, //vb_test_cur + {3, 830}, //vcascp_pixbuf + {4, 1630}, //vcascn_pixbuf + {12, 750}, //vb_pixbuf + {6, 480}, //vref_ds + {5, 1000}, //vb_ds + {7, 400}, //vref_comp + {13, 1220}, //vb_comp + {8, 1500}, //vref_prech + {9, 3000}, //vdd_prot + }; + for(i=0;i<14;++i){ + retval=setDac(dacvalues[i][0], dacvalues[i][1]); + if(retval!=dacvalues[i][1]) + printf("Error: Setting dac %d failed, wrote %d, read %d\n",dacvalues[i][0],dacvalues[i][1],retval); + } + + //power on the chips + bus_w(POWER_ON_REG,0x1); + + //reset adc + writeADC(ADCREG1,0x3); writeADC(ADCREG1,0x0); + writeADC(ADCREG2,0x40); + writeADC(ADCREG3,0xf); + writeADC(ADCREG4,0x3f); + //vrefs - configurable? + writeADC(ADCREG_VREFS,0x2); + + + //set ADCINVERSionreg (by trial and error) + bus_w(ADC_INVERSION_REG,0x453b2a9c); + + //set adc_pipeline + bus_w(ADC_PIPELINE_REG,0x20); //same as ADC_OFFSET_REG + + //set dbit_pipeline + bus_w(DBIT_PIPELINE_REG,0x100e); + usleep(1000000);//1s + + //reset mem machine fifos fifos + bus_w(MEM_MACHINE_FIFOS_REG,0x4000); + bus_w(MEM_MACHINE_FIFOS_REG,0x0); + + //reset run control + bus_w(MEM_MACHINE_FIFOS_REG,0x0400); + bus_w(MEM_MACHINE_FIFOS_REG,0x0); + + //set default setting + setSettings(DYNAMICGAIN,-1); + } + + + //Initialization of acquistion parameters + setFrames(-1); + setTrains(-1); + setExposureTime(-1); + setPeriod(-1); + setDelay(-1); + setGates(-1); + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + setMaster(GET_MASTER); + setSynchronization(GET_SYNCHRONIZATION_MODE); + startReceiver(0); //firmware + }//end of control server only-- + else printf("\n\n"); + + + //common for both control and stop server + strcpy(mess,"dummy message"); + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + lockStatus=0; + // getDynamicRange(); + + /* both these functions setROI and allocateRAM should go into the control server part. */ + if(myDetectorType!=JUNGFRAU){ + int retvalsize,ret; + setROI(-1,NULL,&retvalsize,&ret); + allocateRAM(); + } + + return OK; +} + + +int decode_function(int file_des) { + int fnum,n; + int retval=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveDataOnly(file_des,&fnum,sizeof(fnum)); + if (n <= 0) { +#ifdef VERBOSE + printf("ERROR reading from socket %d, %d %d\n", n, fnum, file_des); +#endif + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif + +#ifdef VERBOSE + printf( "calling function fnum = %d %x %x %x\n",fnum,(unsigned int)(flist[fnum]), (unsigned int)(flist[F_READ_REGISTER]),(unsigned int)(&read_register)); +#endif + if (fnum<0 || fnum>255) + fnum=255; + retval=(*flist[fnum])(file_des); + if (retval==FAIL) + printf( "Error executing the function = %d \n",fnum); + return retval; +} + + +int function_table() { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_EXEC_COMMAND]=&exec_command; + flist[F_GET_DETECTOR_TYPE]=&get_detector_type; + flist[F_SET_NUMBER_OF_MODULES]=&set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES]=&get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG]=&set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE]=&set_external_communication_mode; + flist[F_GET_ID]=&get_id; + flist[F_DIGITAL_TEST]=&digital_test; + flist[F_WRITE_REGISTER]=&write_register; + flist[F_READ_REGISTER]=&read_register; + flist[F_SET_DAC]=&set_dac; + flist[F_GET_ADC]=&get_adc; + flist[F_SET_CHANNEL]=&set_channel; + flist[F_SET_CHIP]=&set_chip; + flist[F_SET_MODULE]=&set_module; + flist[F_GET_CHANNEL]=&get_channel; + flist[F_GET_CHIP]=&get_chip; + flist[F_GET_MODULE]=&get_module; + flist[F_GET_THRESHOLD_ENERGY]=&get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY]=&set_threshold_energy; + flist[F_SET_SETTINGS]=&set_settings; + flist[F_START_ACQUISITION]=&start_acquisition; + flist[F_STOP_ACQUISITION]=&stop_acquisition; + flist[F_START_READOUT]=&start_readout; + flist[F_GET_RUN_STATUS]=&get_run_status; + flist[F_READ_FRAME]=&read_frame; + flist[F_READ_ALL]=&read_all; + flist[F_START_AND_READ_ALL]=&start_and_read_all; + flist[F_SET_TIMER]=&set_timer; + flist[F_GET_TIME_LEFT]=&get_time_left; + flist[F_SET_DYNAMIC_RANGE]=&set_dynamic_range; + flist[F_SET_ROI]=&set_roi; + flist[F_SET_SPEED]=&set_speed; + flist[F_SET_READOUT_FLAGS]=&set_readout_flags; + flist[F_EXECUTE_TRIMMING]=&execute_trimming; + flist[F_LOCK_SERVER]=&lock_server; + flist[F_SET_PORT]=&set_port; + flist[F_GET_LAST_CLIENT_IP]=&get_last_client_ip; + flist[F_UPDATE_CLIENT]=&update_client; + flist[F_CONFIGURE_MAC]=&configure_mac; + flist[F_LOAD_IMAGE]=&load_image; + flist[F_SET_MASTER]=&set_master; + flist[F_SET_SYNCHRONIZATION_MODE]=&set_synchronization; + flist[F_READ_COUNTER_BLOCK]=&read_counter_block; + flist[F_RESET_COUNTER_BLOCK]=&reset_counter_block; + flist[F_START_RECEIVER]=&start_receiver; + flist[F_STOP_RECEIVER]=&stop_receiver; + flist[F_CALIBRATE_PEDESTAL]=&calibrate_pedestal; + flist[F_SET_CTB_PATTERN]=&set_ctb_pattern; + flist[F_WRITE_ADC_REG]=&write_adc_register; + return OK; +} + + +int M_nofunc(int file_des){ + + int ret=FAIL; + sprintf(mess,"Unrecognized Function\n"); + printf(mess); + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + + +int exit_server(int file_des) { + int retval=FAIL; + sendDataOnly(file_des,&retval,sizeof(retval)); + printf("closing server."); + sprintf(mess,"closing server"); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + +int exec_command(int file_des) { + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int retval=OK; + int sysret=0; + int n=0; + + /* receive arguments */ + n = receiveDataOnly(file_des,cmd,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + if (lockStatus==0 || differentClients==0) + sysret=system(cmd); + + //should be replaced by popen + if (sysret==0) { + sprintf(answer,"Succeeded\n"); + if (lockStatus==1 && differentClients==1) + sprintf(answer,"Detector locked by %s\n", lastClientIP); + } else { + sprintf(answer,"Failed\n"); + retval=FAIL; + } + } else { + sprintf(answer,"Could not receive the command\n"); + } + + /* send answer */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + n = sendDataOnly(file_des,answer,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + + /*return ok/fail*/ + return retval; + +} + + + +int get_detector_type(int file_des) { + int n=0; + enum detectorType ret; + int retval=OK; + + sprintf(mess,"Can't return detector type\n"); + + + /* receive arguments */ + /* execute action */ + ret=myDetectorType; + +#ifdef VERBOSE + printf("Returning detector type %d\n",ret); +#endif + + /* send answer */ + /* send OK/failed */ + if (differentClients==1) + retval=FORCE_UPDATE; + + n += sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + + +} + + +int set_number_of_modules(int file_des) { + int n; + int arg[2], ret=0; + int retval=OK; + int dim, nm; + + sprintf(mess,"Can't set number of modules\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket %d", n); + retval=GOODBYE; + } + if (retval==OK) { + dim=arg[0]; + nm=arg[1]; + + /* execute action */ +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + + //if (nm!=GET_FLAG) { + if (dim!=X && nm!=GET_FLAG) { + retval=FAIL; + sprintf(mess,"Can't change module number in dimension %d\n",dim); + } else { + if (lockStatus==1 && differentClients==1 && nm!=GET_FLAG) { + sprintf(mess,"Detector locked by %s\n", lastClientIP); + retval=FAIL; + } else { + ret=setNMod(nm); + if (nModX==nm || nm==GET_FLAG) { + retval=OK; + if (differentClients==1) + retval=FORCE_UPDATE; + } else + retval=FAIL; + } + } + } + /*} else { + if (dim==Y) { + ret=nModY; + } else if (dim==X) { + ret=setNMod(-1); + } + } + */ + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + +} + + +int get_max_number_of_modules(int file_des) { + int n; + int ret; + int retval=OK; + enum dimension arg; + + sprintf(mess,"Can't get max number of modules\n"); + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* execute action */ +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif + + + switch (arg) { + case X: + ret=getNModBoard(); + break; + case Y: + ret=NMAXMODY; + break; + default: + ret=FAIL; + retval=FAIL; + break; + } +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,ret ); +#endif + + + + if (differentClients==1 && retval==OK) { + retval=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + + /*return ok/fail*/ + return retval; +} + + +//index 0 is in gate +//index 1 is in trigger +//index 2 is out gate +//index 3 is out trigger + +int set_external_signal_flag(int file_des) { + int n; + int arg[2]; + int ret=OK; + int signalindex; + enum externalSignalFlag flag, retval; + + sprintf(mess,"Can't set external signal flag\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + retval=SIGNAL_OFF; + if (ret==OK) { + signalindex=arg[0]; + flag=arg[1]; + /* execute action */ + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + + default: + if (differentClients==0 || lockStatus==0) { + retval=setExtSignal(signalindex,flag); + } else { + if (lockStatus!=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n", lastClientIP); + } + } + + } + +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag ); + printf("Set to flag %d\n",retval); +#endif + + } else { + ret=FAIL; + } + + if (ret==OK && differentClients!=0) + ret=FORCE_UPDATE; + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + +int set_external_communication_mode(int file_des) { + int n; + enum externalCommunicationMode arg, ret=GET_EXTERNAL_COMMUNICATION_MODE; + int retval=OK; + + sprintf(mess,"Can't set external communication mode\n"); + + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* + enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE + }; + */ + if (retval==OK) { + /* execute action */ + + ret=setTiming(arg); + + /* switch(arg) { */ + /* default: */ + /* sprintf(mess,"The meaning of single signals should be set\n"); */ + /* retval=FAIL; */ + /* } */ + + +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif + } else + ret=FAIL; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return retval; +} + + + +int get_id(int file_des) { + // sends back 64 bits! + int64_t retval=-1; + int ret=OK; + int n=0; + enum idMode arg; + + sprintf(mess,"Can't return id\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + + switch (arg) { + case DETECTOR_SERIAL_NUMBER: + retval=getDetectorNumber(); + break; + case DETECTOR_FIRMWARE_VERSION: + retval=getFirmwareSVNVersion(); + retval=(retval <<32) | getFirmwareVersion(); + break; + case DETECTOR_SOFTWARE_VERSION: + retval= SVNREV; + retval= (retval <<32) | SVNDATE; + break; +/* case DETECTOR_FIRMWARE_SVN_VERSION: + retval=getFirmwareSVNVersion(); + break;*/ + default: + printf("Required unknown id %d \n", arg); + ret=FAIL; + retval=FAIL; + break; + } + +#ifdef VERBOSE + printf("Id is %llx\n", retval); +#endif + + if (differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int digital_test(int file_des) { + + int retval; + int ret=OK; + int imod=-1; + int n=0; + int ibit=0; + int ow; + int ival; + enum digitalTestMode arg; + + sprintf(mess,"Can't send digital test\n"); + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Digital test mode %d\n",arg ); +#endif + + switch (arg) { + case CHIP_TEST: + n = receiveDataOnly(file_des,&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + retval=0; +#ifdef MCB_FUNCS + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + break; + } + if (imod >= nModX) { + ret=FAIL; + sprintf(mess,"Module %d disabled\n",imod); + break; + } + if (testShiftIn(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftOut(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftStSel(imod)) retval|=(1<<(ibit)); + ibit++; + //if ( testDataInOut(0x123456, imod)) retval|=(1<<(ibit++)); + //if ( testExtPulse(imod)) retval|=(1<<(ibit++)); + // for (ow=0; ow<6; ow++) + // ow=1; + //#ifndef PICASSOD + for (ow=0; ow<5; ow++) { + //#endif + if (testDataInOutMux(imod, ow, 0x789abc)) retval|=(1<=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + + + + +#ifdef MCB_FUNCS + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + if (ind<16) { + + if (mV) { + if (val>2500) + val=-1; + printf("%d mV is ",val); + if (val>0) + val=4095*val/2500; + printf("%d DACu\n", val); + } else if (val>4095) + val=-1; + + + retval=setDac(ind,val); + /* if(idac==HIGH_VOLTAGE) */ + /* retval=initHighVoltageByModule(val,imod); */ + /* else */ + /* retval=initDACbyIndexDACU(idac,val,imod); */ + } + else if (ind==ADC_VPP) { + printf("Setting ADC VPP to %d\n",val); + if (val>4 || val<0) + printf("Cannot set ADC VPP to %d\n",val); + else { + writeADC(0x18,val); + adcvpp=val; + } + retval=adcvpp;; + + } else if (ind==HV_NEW ) + retval=initHighVoltageByModule(val,imod); + else + printf("**********No dac with index %d\n",ind); + } + } + if(ret==OK){ + if (ind<16) { + if (mV) { + + printf("%d DACu is ",retval); + retval1=2500*retval/16535; + printf("%d mV \n",retval1); + } else + retval1=retval; + } else + retval1=retval; + } +#endif + +#ifdef VERBOSE + printf("DAC set to %d V\n", retval); +#endif + + if(ret==FAIL) + printf("Setting dac %d of module %d: wrote %d but read %d\n", ind, imod, val, retval); + else{ + if (differentClients) + ret=FORCE_UPDATE; + } + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + n += sendDataOnly(file_des,&retval1,sizeof(retval1)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + +int get_adc(int file_des) { + //default: mod 0 + int retval; + int ret=OK; + int arg[2]; + enum dacIndex ind; + int imod; + int n; + int idac=0; + + sprintf(mess,"Can't read ADC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ind=arg[0]; + imod=arg[1]; + +#ifdef VERBOSE + printf("Getting ADC %d of module %d\n", ind, imod); +#endif + + if (imod>=getNModBoard() || imod<0) + ret=FAIL; + +#ifdef MCB_FUNCS + switch (ind) { + case TEMPERATURE_FPGA: + idac=TEMP_FPGA; + break; + case TEMPERATURE_ADC: + idac=TEMP_ADC; + break; + default: + printf("Unknown DAC index %d\n",ind); + sprintf(mess,"Unknown DAC index %d\n",ind); + ret=FAIL; + break; + } + + if (ret==OK) + retval=getTemperatureByModule(idac,imod); +#endif + +#ifdef VERBOSE + printf("ADC is %d V\n", retval); +#endif + if (ret==FAIL) { + printf("Getting adc %d of module %d failed\n", ind, imod); + } + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int set_channel(int file_des) { + int ret=OK; + sls_detector_channel myChan; + int retval; + int n; + + + sprintf(mess,"Can't set channel\n"); + +#ifdef VERBOSE + printf("Setting channel\n"); +#endif + ret=receiveChannel(file_des, &myChan); + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif + + if (ret==OK) { + if (myChan.module>=getNModBoard()) + ret=FAIL; + if (myChan.chip>=N_CHIP) + ret=FAIL; + if (myChan.chan>=N_CHAN) + ret=FAIL; + if (myChan.module<0) + myChan.module=ALLMOD; + } + + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChannelbyNumber(myChan); +#endif + } + } + /* Maybe this is done inside the initialization funcs */ + //copyChannel(detectorChans[myChan.module][myChan.chip]+(myChan.chan), &myChan); + + + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + + +int get_channel(int file_des) { + + int ret=OK; + sls_detector_channel retval; + + int arg[3]; + int ichan, ichip, imod; + int n; + + sprintf(mess,"Can't get channel\n"); + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichan=arg[0]; + ichip=arg[1]; + imod=arg[2]; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0 && ichan=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + + if (ret==OK) { + if (myChip.module>=getNModBoard()) + ret=FAIL; + if (myChip.module<0) + myChip.module=ALLMOD; + if (myChip.chip>=N_CHIP) + ret=FAIL; + } + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChipbyNumber(myChip); +#endif + } + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + return ret; +} + +int get_chip(int file_des) { + + + int ret=OK; + sls_detector_chip retval; + int arg[2]; + int ichip, imod; + int n; + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichip=arg[0]; + imod=arg[1]; + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0) + ret=OK; + else + ret=FAIL; + + +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#endif + + if (ret==OK) { + if (myModule.module>=getNModBoard()) { + ret=FAIL; + printf("Module number is too large %d\n",myModule.module); + } + if (myModule.module<0) + myModule.module=ALLMOD; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initModulebyNumber(myModule); + if(retval != myModule.reg) + ret = FAIL; +#endif + } + } + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + free(myDac); + if(myAdc != NULL) free(myAdc); + if(myChip != NULL) free(myChip); + if(myChan != NULL) free(myChan); + + + //setDynamicRange(dr); always 16 commented out + + return ret; +} + + + + +int get_module(int file_des) { + + int ret=OK; + int arg; + int imod; + int n; + sls_detector_module myModule; + int *myDac=malloc(N_DAC*sizeof(int)); + int *myChip=NULL; + int *myChan=NULL; + int *myAdc=NULL; + + /*not required for jungfrau. so save memory*/ + if(myDetectorType != JUNGFRAU){ + myChip=malloc(N_CHIP*sizeof(int)); + myChan=malloc(N_CHIP*N_CHAN*sizeof(int)); + myAdc=malloc(N_ADC*sizeof(int)); + } + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + + + myModule.adcs=NULL; + myModule.chipregs=NULL; + myModule.chanregs=NULL; + /*not required for jungfrau. so save memory*/ + if(myDetectorType != JUNGFRAU){ + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } + } + + myModule.ndac=N_DAC; + myModule.nchip=N_CHIP; + myModule.nchan=N_CHAN*N_CHIP; + myModule.nadc=N_ADC; + + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + imod=arg; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod-1) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + if (differentClients) + dataret=FORCE_UPDATE; + } +#ifdef VERBOSE + printf("Frames left %d\n",(int)(getFrames())); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + } + + + + + return dataret; + +} + + + + + + + + +int read_all(int file_des) { + +while(read_frame(file_des)==OK) { + +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + return OK; + + +} + +int start_and_read_all(int file_des) { + //int dataret=OK; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + if (differentClients==1 && lockStatus==1) { + dataret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return dataret; + + } + + startStateMachine(); + + /* ret=startStateMachine(); + if (ret!=OK) { + sprintf(mess,"could not start state machine\n"); + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + #ifdef VERBOSE + printf("could not start state machine\n"); +#endif +} else {*/ + read_all(file_des); +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + //} + + + return OK; + + +} + +int set_timer(int file_des) { + enum timerIndex ind; + int64_t tns; + int n; + int64_t retval; + int ret=OK; + + + sprintf(mess,"can't set timer\n"); + + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&tns,sizeof(tns)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret!=OK) { + printf(mess); + } + +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif + if (ret==OK) { + + if (differentClients==1 && lockStatus==1 && tns!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch(ind) { + case FRAME_NUMBER: + retval=setFrames(tns); + break; + case ACQUISITION_TIME: + retval=setExposureTime(tns); + break; + case FRAME_PERIOD: + retval=setPeriod(tns); + break; + case DELAY_AFTER_TRIGGER: + retval=setDelay(tns); + break; + case GATES_NUMBER: + retval=setGates(tns); + break; + case PROBES_NUMBER: + sprintf(mess,"can't set timer for moench\n"); + ret=FAIL; + break; + case CYCLES_NUMBER: + retval=setTrains(tns); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + } + if (ret!=OK) { + printf(mess); + if (differentClients) + ret=FORCE_UPDATE; + } + + if (ret!=OK) { + printf(mess); + printf("set timer failed\n"); + } else if (ind==FRAME_NUMBER) { + // ret=allocateRAM(); + // if (ret!=OK) + // sprintf(mess, "could not allocate RAM for %lld frames\n", tns); + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { +#ifdef VERBOSE + printf("returning ok %d\n",(int)(sizeof(retval))); +#endif + + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + + return ret; + +} + + + + + + + + +int get_time_left(int file_des) { + + enum timerIndex ind; + int n; + int64_t retval; + int ret=OK; + + sprintf(mess,"can't get timer\n"); + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + //#ifdef VERBOSE + + printf("getting time left on timer %d \n",ind); + //#endif + + if (ret==OK) { + switch(ind) { + case FRAME_NUMBER: + printf("getting frames \n"); + retval=getFrames(); + break; + case ACQUISITION_TIME: + retval=getExposureTime(); + break; + case FRAME_PERIOD: + retval=getPeriod(); + break; + case DELAY_AFTER_TRIGGER: + retval=getDelay(); + break; + case GATES_NUMBER: + retval=getGates(); + break; + case PROBES_NUMBER: + retval=getProbes(); + break; + case CYCLES_NUMBER: + retval=getTrains(); + break; + case PROGRESS: + retval=getProgress(); + break; + case ACTUAL_TIME: + retval=getActualTime(); + break; + case MEASUREMENT_TIME: + retval=getMeasurementTime(); + break; + case FRAMES_FROM_START: + case FRAMES_FROM_START_PG: + retval=getFramesFromStart(); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + + + if (ret!=OK) { + printf("get time left failed\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + + //#ifdef VERBOSE + + printf("time left on timer %d is %lld\n",ind, retval); + //#endif + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } else + n = sendDataOnly(file_des,&retval,sizeof(retval)); + +#ifdef VERBOSE + + printf("data sent\n"); +#endif + + return ret; + + +} + +int set_dynamic_range(int file_des) { + + + + int dr; + int n; + int retval; + int ret=OK; + + printf("Set dynamic range?\n"); + sprintf(mess,"can't set dynamic range\n"); + + + n = receiveDataOnly(file_des,&dr,sizeof(dr)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + if (differentClients==1 && lockStatus==1 && dr>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setDynamicRange(dr); + } + + //if (dr>=0 && retval!=dr) ret=FAIL; + if (ret!=OK) { + sprintf(mess,"set dynamic range failed\n"); + } else { + /* ret=allocateRAM(); */ +/* if (ret!=OK) */ +/* sprintf(mess,"Could not allocate RAM for the dynamic range selected\n"); */ +// else + if (differentClients) + ret=FORCE_UPDATE; + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + +int set_roi(int file_des) { + + int i; + int ret=OK; + int nroi=-1; + int n=0; + int retvalsize=0; + ROI arg[MAX_ROIS]; + ROI* retval=0; + strcpy(mess,"Could not set/get roi\n"); + // u_int32_t disable_reg=0; + + n = receiveDataOnly(file_des,&nroi,sizeof(nroi)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if(myDetectorType == JUNGFRAU){ + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); + printf("Error:Set ROI-%s",mess); + } + + else{ + + if(nroi>=0){ + n = receiveDataOnly(file_des,arg,nroi*sizeof(ROI)); + if (n != (nroi*sizeof(ROI))) { + sprintf(mess,"Received wrong number of bytes for ROI\n"); + ret=FAIL; + } + + printf("Setting ROI to:"); + for( i=0;i=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch (arg) { + case CLOCK_DIVIDER: + retval=setClockDivider(val,0); + break; + +/* case PHASE_SHIFT: */ +/* retval=phaseStep(val,0); */ +/* break; */ + + case OVERSAMPLING: + retval=setOversampling(val); + break; + + case ADC_CLOCK: + retval=setClockDivider(val,1); + break; + +/* case ADC_PHASE: */ +/* retval=phaseStep(val,1); */ +/* break; */ + + + case ADC_PIPELINE: + retval=adcPipeline(val); + break; + + + + default: + ret=FAIL; + sprintf(mess,"Unknown speed parameter %d",arg); + } + } + } + + + } + + + switch (arg) { + case CLOCK_DIVIDER: + retval=getClockDivider(0); + break; + + case PHASE_SHIFT: + retval=getPhase(); + // retval=phaseStep(-1); + //ret=FAIL; + //sprintf(mess,"Cannot read phase",arg); + break; + + case OVERSAMPLING: + retval=setOversampling(-1); + break; + + case ADC_CLOCK: + retval=getClockDivider(1); + break; + + case ADC_PHASE: + retval=getPhase(); + break; + + + case ADC_PIPELINE: + retval=adcPipeline(-1); + break; + + + default: + ret=FAIL; + sprintf(mess,"Unknown speed parameter %d",arg); + } + } + + + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + +int set_readout_flags(int file_des) { + + enum readOutFlags arg; + int ret=FAIL; + + + receiveDataOnly(file_des,&arg,sizeof(arg)); + + sprintf(mess,"can't set readout flags for moench\n"); + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + return ret; +} + + + + + +int execute_trimming(int file_des) { + + int arg[3]; + int ret=FAIL; + enum trimMode mode; + + sprintf(mess,"can't set execute trimming for moench\n"); + + receiveDataOnly(file_des,&mode,sizeof(mode)); + receiveDataOnly(file_des,arg,sizeof(arg)); + + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + return ret; +} + + +int lock_server(int file_des) { + + + int n; + int ret=OK; + + int lock; + n = receiveDataOnly(file_des,&lock,sizeof(lock)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (lock)\n"); + ret=FAIL; + } + if (lock>=0) { + if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) + lockStatus=lock; + else { + ret=FAIL; + sprintf(mess,"Server already locked by %s\n", lastClientIP); + } + } + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else + n = sendDataOnly(file_des,&lockStatus,sizeof(lockStatus)); + + return ret; + +} + +int set_port(int file_des) { + int n; + int ret=OK; + int sd=-1; + + enum portType p_type; /** data? control? stop? Unused! */ + int p_number; /** new port number */ + + n = receiveDataOnly(file_des,&p_type,sizeof(p_type)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (ptype)\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&p_number,sizeof(p_number)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (pnum)\n"); + ret=FAIL; + } + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + printf("\n"); + ret=FAIL; + } + + printf("set port %d to %d\n",p_type, p_number); + + sd=bindSocket(p_number); + } + if (sd>=0) { + ret=OK; + if (differentClients ) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + printf("Could not bind port %d\n", p_number); + if (sd==-10) { + sprintf(mess,"Port %d already set\n", p_number); + printf("Port %d already set\n", p_number); + + } + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&p_number,sizeof(p_number)); + closeConnection(file_des); + exitServer(sockfd); + sockfd=sd; + + } + + return ret; + +} + +int get_last_client_ip(int file_des) { + int ret=OK; + int n; + if (differentClients ) + ret=FORCE_UPDATE; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + + return ret; + +} + + +int send_update(int file_des) { + + int ret=OK; + enum detectorSettings t; + int n;//int thr, n; + //int it; + int64_t retval, tns=-1; + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + n = sendDataOnly(file_des,&nModX,sizeof(nModX)); + n = sendDataOnly(file_des,&nModY,sizeof(nModY)); + n = sendDataOnly(file_des,&dynamicRange,sizeof(dynamicRange)); + n = sendDataOnly(file_des,&dataBytes,sizeof(dataBytes)); + t=setSettings(GET_SETTINGS,-1); + n = sendDataOnly(file_des,&t,sizeof(t)); +/* thr=getThresholdEnergy(); + n = sendDataOnly(file_des,&thr,sizeof(thr));*/ + retval=setFrames(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setExposureTime(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setPeriod(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setDelay(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setGates(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); +/* retval=setProbes(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t));*/ + retval=setTrains(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + + if (lockStatus==0) { + strcpy(lastClientIP,thisClientIP); + } + + return ret; + + +} +int update_client(int file_des) { + + int ret=OK; + + sendDataOnly(file_des,&ret,sizeof(ret)); + return send_update(file_des); + + + +} + + +int configure_mac(int file_des) { + + int ret=OK; + char arg[5][50]; + int n; + + int imod=0;//should be in future sent from client as -1, arg[2] + int ipad; + long long int imacadd; + long long int idetectormacadd; + int udpport; + int detipad; + int retval=-100; + + sprintf(mess,"Can't configure MAC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + sscanf(arg[0], "%x", &ipad); + sscanf(arg[1], "%llx", &imacadd); + sscanf(arg[2], "%x", &udpport); + sscanf(arg[3], "%llx", &idetectormacadd); + sscanf(arg[4], "%x", &detipad); + + //#ifdef VERBOSE + int i; + printf("\ndigital_test_bit in server %d\t",digitalTestBit); + printf("\nipadd %x\t",ipad); + printf("destination ip is %d.%d.%d.%d = 0x%x \n",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff,ipad); + printf("macad:%llx\n",imacadd); + for (i=0;i<6;i++) + printf("mac adress %d is 0x%x \n",6-i,(unsigned int)(((imacadd>>(8*i))&0xFF))); + printf("udp port:0x%x\n",udpport); + printf("detector macad:%llx\n",idetectormacadd); + for (i=0;i<6;i++) + printf("detector mac adress %d is 0x%x \n",6-i,(unsigned int)(((idetectormacadd>>(8*i))&0xFF))); + printf("detipad %x\n",detipad); + printf("\n"); + //#endif + + + + if (imod>=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + + //#ifdef VERBOSE + printf("Configuring MAC of module %d at port %x\n", imod, udpport); + //#endif +#ifdef MCB_FUNCS + if (ret==OK){ + if(runBusy()){ + ret=stopStateMachine(); + if(ret==FAIL) + strcpy(mess,"could not stop detector acquisition to configure mac"); + } + + if(ret==OK) + configureMAC(ipad,imacadd,idetectormacadd,detipad,digitalTestBit,udpport); + retval=getAdcConfigured(); + } +#endif + if (ret==FAIL) + printf("configuring MAC of mod %d failed\n", imod); + else + printf("Configuremac successful of mod %d and adc %d\n",imod,retval); + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + /*return ok/fail*/ + return ret; + +} + + + +int load_image(int file_des) { + int retval; + int ret=OK; + int n; + enum imageType index; + short int ImageVals[N_CHAN*N_CHIP]; + + sprintf(mess,"Loading image failed\n"); + + n = receiveDataOnly(file_des,&index,sizeof(index)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,ImageVals,dataBytes); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + switch (index) { + case DARK_IMAGE : +#ifdef VERBOSE + printf("Loading Dark image\n"); +#endif + break; + case GAIN_IMAGE : +#ifdef VERBOSE + printf("Loading Gain image\n"); +#endif + break; + default: + printf("Unknown index %d\n",index); + sprintf(mess,"Unknown index %d\n",index); + ret=FAIL; + break; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + retval=loadImage(index,ImageVals); + if (retval==-1) + ret = FAIL; + } + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + +int set_master(int file_des) { + + enum masterFlags retval=GET_MASTER; + enum masterFlags arg; + int n; + int ret=OK; + // int regret=OK; + + + sprintf(mess,"can't set master flags\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setMaster(arg); + + } + if (retval==GET_MASTER) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int set_synchronization(int file_des) { + + enum synchronizationMode retval=GET_MASTER; + enum synchronizationMode arg; + int n; + int ret=OK; + //int regret=OK; + + + sprintf(mess,"can't set synchronization mode\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + //ret=setStoreInRAM(0); + // initChipWithProbes(0,0,0, ALLMOD); + retval=setSynchronization(arg); + } + if (retval==GET_SYNCHRONIZATION_MODE) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int read_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + //char *retval=NULL; + short int CounterVals[N_CHAN*N_CHIP]; + + sprintf(mess,"Read counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + ret=readCounterBlock(startACQ,CounterVals); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,CounterVals[i]); +#endif + } + } + + if(ret!=FAIL){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,CounterVals,dataBytes);//1280*2 + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + + + +int reset_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + + sprintf(mess,"Reset counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=resetCounterBlock(startACQ); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + + /*return ok/fail*/ + return ret; +} + + + + + + +int start_receiver(int file_des) { + int ret=OK; + int n=0; + strcpy(mess,"Could not start receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret = startReceiver(1); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + + +int stop_receiver(int file_des) { + int ret=OK; + int n=0; + + strcpy(mess,"Could not stop receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret=startReceiver(0); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + +int calibrate_pedestal(int file_des){ + + int ret=OK; + int retval=-1; + int n; + int frames; + + sprintf(mess,"Could not calibrate pedestal\n"); + + n = receiveDataOnly(file_des,&frames,sizeof(frames)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=calibratePedestal(frames); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + + /*return ok/fail*/ + return ret; +} + + +int set_ctb_pattern(int file_des){ + + int ret=OK;//FAIL; + int retval=-1; + int n; + int mode; + uint64_t word, retval64, t; + int addr; + int level, start, stop, nl; + uint64_t pat[1024]; + + sprintf(mess,"Could not set pattern\n"); + + n = receiveDataOnly(file_des,&mode,sizeof(mode)); + printf("pattern mode is %d\n",mode); + switch (mode) { + + case 0: //sets word + n = receiveDataOnly(file_des,&addr,sizeof(addr)); + n = receiveDataOnly(file_des,&word,sizeof(word)); + ret=OK; + + switch (addr) { + case -1: + retval64=writePatternIOControl(word); + break; + case -2: + retval64=writePatternClkControl(word); + break; + default: + retval64=writePatternWord(addr,word); + }; + + + //write word; + //@param addr address of the word, -1 is I/O control register, -2 is clk control register + //@param word 64bit word to be written, -1 gets + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval64,sizeof(retval64)); + break; + + case 1: //pattern loop + n = receiveDataOnly(file_des,&level,sizeof(level)); + n = receiveDataOnly(file_des,&start,sizeof(start)); + n = receiveDataOnly(file_des,&stop,sizeof(stop)); + n = receiveDataOnly(file_des,&nl,sizeof(nl)); + + + + printf("level %d start %x stop %x nl %d\n",level, start, stop, nl); + /** Sets the pattern or loop limits in the CTB + @param level -1 complete pattern, 0,1,2, loop level + @param start start address if >=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ + ret=setPatternLoop(level, &start, &stop, &nl); + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else { + n += sendDataOnly(file_des,&start,sizeof(start)); + n += sendDataOnly(file_des,&stop,sizeof(stop)); + n += sendDataOnly(file_des,&nl,sizeof(nl)); + } + break; + + + + case 2: //wait address + n = receiveDataOnly(file_des,&level,sizeof(level)); + n = receiveDataOnly(file_des,&addr,sizeof(addr)); + + + + /** Sets the wait address in the CTB + @param level 0,1,2, wait level + @param addr wait address, -1 gets + @returns actual value + */ + printf("wait addr %d %x\n",level, addr); + retval=setPatternWaitAddress(level,addr); + printf("ret: wait addr %d %x\n",level, retval); + ret=OK; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else { + n += sendDataOnly(file_des,&retval,sizeof(retval)); + + } + + + break; + + + case 3: //wait time + n = receiveDataOnly(file_des,&level,sizeof(level)); + n = receiveDataOnly(file_des,&t,sizeof(t)); + + + /** Sets the wait time in the CTB + @param level 0,1,2, wait level + @param t wait time, -1 gets + @returns actual value + */ + + ret=OK; + + retval64=setPatternWaitTime(level,t); + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval64,sizeof(retval64)); + + break; + + + + case 4: + n = receiveDataOnly(file_des,pat,sizeof(pat)); + for (addr=0; addr<1024; addr++) + writePatternWord(addr,word); + ret=OK; + retval=0; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval64,sizeof(retval64)); + + break; + + + + + + default: + ret=FAIL; + printf(mess); + sprintf(mess,"%s - wrong mode %d\n",mess, mode); + n = sendDataOnly(file_des,&ret,sizeof(ret)); + n += sendDataOnly(file_des,mess,sizeof(mess)); + + + + } + + + /*return ok/fail*/ + return ret; +} + + +int write_adc_register(int file_des) { + + int retval; + int ret=OK; + int arg[2]; + int addr, val; + int n; + + sprintf(mess,"Can't write to register\n"); + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + addr=arg[0]; + val=arg[1]; + +#ifdef VERBOSE + printf("writing to register 0x%x data 0x%x\n", addr, val); +#endif + + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } + + + if(ret!=FAIL){ + ret=writeADC(addr,val); + if (ret==OK) + retval=val; + } + + +#ifdef VERBOSE + printf("Data set to 0x%x\n", retval); +#endif + if (retval==val) { + ret=OK; + if (differentClients) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Writing to register 0x%x failed: wrote 0x%x but read 0x%x\n", addr, val, retval); + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} diff --git a/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h new file mode 100755 index 000000000..2d674a1d0 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/server_funcs.h @@ -0,0 +1,98 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H + + +#include "sls_detector_defs.h" + + +#include +/* +#include +#include +#include +*/ +#include "communication_funcs.h" + + + + +#define GOODBYE -200 + +int sockfd; + +int function_table(); + +int decode_function(int); +int init_detector(int,int); + +int M_nofunc(int); +int exit_server(int); + + + + +// General purpose functions +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); + + +int exec_command(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +int write_register(int); +int read_register(int); +int set_dac(int); +int get_adc(int); +int set_channel(int); +int set_chip(int); +int set_module(int); +int get_channel(int); +int get_chip(int); +int get_module(int); + +int get_threshold_energy(int); +int set_threshold_energy(int); +int set_settings(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int read_frame(int); +int read_all(int); +int start_and_read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_roi(int); +int get_roi(int); +int set_speed(int); +int set_readout_flags(int); +int execute_trimming(int); +int lock_server(int); +int set_port(int); +int get_last_client_ip(int); +int set_master(int); +int set_synchronization(int); + +int update_client(int); +int send_update(int); +int configure_mac(int); + +int load_image(int); +int read_counter_block(int); +int reset_counter_block(int); + +int start_receiver(int); +int stop_receiver(int); + + +int calibrate_pedestal(int); + +int set_roi(int); +int set_ctb_pattern(int); + +int write_adc_register(int);; +#endif diff --git a/slsDetectorSoftware/jungfrauDetectorServer/sharedmemory.c b/slsDetectorSoftware/jungfrauDetectorServer/sharedmemory.c new file mode 100755 index 000000000..4504cfe05 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/sharedmemory.c @@ -0,0 +1,39 @@ +#include "sharedmemory.h" + +struct statusdata *stdata; + +int inism(int clsv) { + +static int scansmid; + + if (clsv==SMSV) { + if ( (scansmid=shmget(SMKEY,1024,IPC_CREAT | 0666 ))==-1 ) { + return -1; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -2; + } + } + + if (clsv==SMCL) { + if ( (scansmid=shmget(SMKEY,0,0) )==-1 ) { + return -3; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -4; + } + } + return 1; +} + +void write_status_sm(char *status) { + strcpy(stdata->status,status); +} + +void write_stop_sm(int v) { + stdata->stop=v; +} + +void write_runnumber_sm(int v) { + stdata->runnumber=v; +} diff --git a/slsDetectorSoftware/jungfrauDetectorServer/sharedmemory.h b/slsDetectorSoftware/jungfrauDetectorServer/sharedmemory.h new file mode 100755 index 000000000..bdbddf719 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/sharedmemory.h @@ -0,0 +1,48 @@ +#ifndef SM +#define SM + +#include "sls_detector_defs.h" + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +/* key for shared memory */ +#define SMKEY 10001 + +#define SMSV 1 +#define SMCL 2 + + +struct statusdata { + int runnumber; + int stop; + char status[20]; +} ; + + +/* for shared memory */ + +int inism(int clsv); +void write_status_sm(char *status); +void write_stop_sm(int v); +void write_runnumber_sm(int v); + +#endif diff --git a/slsDetectorSoftware/jungfrauDetectorServer/sls_detector_defs.h b/slsDetectorSoftware/jungfrauDetectorServer/sls_detector_defs.h new file mode 120000 index 000000000..c5062e03f --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/sls_detector_defs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/sls_detector_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/sls_detector_funcs.h new file mode 120000 index 000000000..844b67129 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/sls_detector_funcs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/sls_receiver_defs.h b/slsDetectorSoftware/jungfrauDetectorServer/sls_receiver_defs.h new file mode 120000 index 000000000..1de31caf5 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/sls_receiver_defs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/sls_receiver_funcs.h b/slsDetectorSoftware/jungfrauDetectorServer/sls_receiver_funcs.h new file mode 120000 index 000000000..c2ea4ded9 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/sls_receiver_funcs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/jungfrauDetectorServer/stop_server.c b/slsDetectorSoftware/jungfrauDetectorServer/stop_server.c new file mode 100755 index 000000000..e3c8ff7e1 --- /dev/null +++ b/slsDetectorSoftware/jungfrauDetectorServer/stop_server.c @@ -0,0 +1,46 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + + +#include "sls_detector_defs.h" + + +#include "communication_funcs.h" +#include "firmware_funcs.h" + + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + + portno = DEFAULT_PORTNO; + + + bindSocket(portno); + if (getServerError()) + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + acceptConnection(); + retval=stopStateMachine(); + closeConnection(); + } + + exitServer(); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/moenchDetectorServer/.target-makefrag b/slsDetectorSoftware/moenchDetectorServer/.target-makefrag new file mode 100755 index 000000000..ce093ecac --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/.target-makefrag @@ -0,0 +1 @@ +AXIS_BUILDTYPE ?= cris-axis-linux-gnu diff --git a/slsDetectorSoftware/moenchDetectorServer/Makefile b/slsDetectorSoftware/moenchDetectorServer/Makefile new file mode 100755 index 000000000..b067de322 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/Makefile @@ -0,0 +1,48 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + + +CROSS = bfin-uclinux- +CC = $(CROSS)gcc + +CFLAGS += -Wall -DMOENCHD -DMCB_FUNCS -DDACS_INT -DDEBUG #-DVERBOSE #-DVERYVERBOSE #-DVIRTUAL #-DDACS_INT_CSERVER + + +PROGS= moenchDetectorServer +INSTDIR= /tftpboot +INSTMODE= 0777 + + + +BINS = testlib_sharedlibc +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + + + +all: clean $(PROGS) + +boot: $(OBJS) + +$(PROGS): $(OBJS) + echo $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + + +romfs: + $(ROMFSINST) /bin/$(PROGS) + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/moenchDetectorServer/Makefile.virtual b/slsDetectorSoftware/moenchDetectorServer/Makefile.virtual new file mode 100755 index 000000000..38dd2537c --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/Makefile.virtual @@ -0,0 +1,30 @@ + +DESTDIR ?= ./ + +CC = gcc +CFLAGS += -Wall -DMOENCHD -DMCB_FUNCS -DDACS_INT -DDEBUG -DVIRTUAL + + +PROGS= $(DESTDIR)/moenchVirtualServer + + +SRCS = server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS = $(SRCS:%.c=%.o) + +moenchVirtualServer = $(PROGS) + +all: clean $(PROGS) + + +$(PROGS): $(OBJS) + $(CC) $(CFLAGS) -o $@ $^ $(LDLIBS_$@) $(LDFLAGS_$@) + + +clean: + rm -rf $(PROGS) *.o *.gdb + + + + + + diff --git a/slsDetectorSoftware/moenchDetectorServer/ansi.h b/slsDetectorSoftware/moenchDetectorServer/ansi.h new file mode 120000 index 000000000..a122db0ad --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/ansi.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/slsDetectorSoftware/moenchDetectorServer/communication_funcs.c b/slsDetectorSoftware/moenchDetectorServer/communication_funcs.c new file mode 120000 index 000000000..87a4f95d1 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/communication_funcs.c @@ -0,0 +1 @@ +../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/moenchDetectorServer/communication_funcs.h b/slsDetectorSoftware/moenchDetectorServer/communication_funcs.h new file mode 120000 index 000000000..f220903b2 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/communication_funcs.h @@ -0,0 +1 @@ +../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/moenchDetectorServer/firmware_funcs.c b/slsDetectorSoftware/moenchDetectorServer/firmware_funcs.c new file mode 100755 index 000000000..25b6e7598 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/firmware_funcs.c @@ -0,0 +1,2613 @@ + +#include "server_defs.h" +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers_m.h" + +#ifdef SHAREDMEMORY +#include "sharedmemory.h" +#endif + +#include +#include +#include + +#include + +//for memory mapping +u_int64_t CSP0BASE; + +FILE *debugfp, *datafp; + +int fr; +int wait_time; +int *fifocntrl; + +//int *statusreg; commented out by dhanya +const int nModY=1; +int nModBoard; +int nModX=NMAXMOD; +int dynamicRange=16;//32; +int dataBytes=NMAXMOD*NCHIP*NCHAN*2; +int storeInRAM=0; +int ROI_flag=0; +int adcConfigured=-1; +u_int32_t *ram_values=NULL; +volatile char *now_ptr=NULL; +volatile u_int16_t *values; +int ram_size=0; + +int64_t totalTime=1; +u_int32_t progressMask=0; + +int phase_shift=0;//DEFAULT_PHASE_SHIFT; +int ipPacketSize=DEFAULT_IP_PACKETSIZE; +int udpPacketSize=DEFAULT_UDP_PACKETSIZE; + + +int ififostart, ififostop, ififostep, ififo; + +int masterMode=NO_MASTER, syncMode=NO_SYNCHRONIZATION, timingMode=AUTO_TIMING; + +enum externalSignalFlag signals[4]={EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF, EXT_SIG_OFF}; + + +#ifdef MCB_FUNCS +extern const int nChans; +extern const int nChips; +//extern const int nDacs; +//extern const int nAdcs; +#endif +#ifndef MCB_FUNCS + +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +#endif + + + + +/** + ENEt conf structs +*/ +typedef struct mac_header_struct{ + u_int8_t mac_dest_mac2; + u_int8_t mac_dest_mac1; + u_int8_t mac_dummy1; + u_int8_t mac_dummy2; + u_int8_t mac_dest_mac6; + u_int8_t mac_dest_mac5; + u_int8_t mac_dest_mac4; + u_int8_t mac_dest_mac3; + u_int8_t mac_src_mac4; + u_int8_t mac_src_mac3; + u_int8_t mac_src_mac2; + u_int8_t mac_src_mac1; + u_int16_t mac_ether_type; + u_int8_t mac_src_mac6; + u_int8_t mac_src_mac5; +} mac_header; + +typedef struct ip_header_struct { + u_int16_t ip_len; + u_int8_t ip_tos; + u_int8_t ip_ihl:4 ,ip_ver:4; + u_int16_t ip_offset:13,ip_flag:3; + u_int16_t ip_ident; + u_int16_t ip_chksum; + u_int8_t ip_protocol; + u_int8_t ip_ttl; + u_int32_t ip_sourceip; + u_int32_t ip_destip; +} ip_header; + +typedef struct udp_header_struct{ + u_int16_t udp_destport; + u_int16_t udp_srcport; + u_int16_t udp_chksum; + u_int16_t udp_len; +} udp_header; + +typedef struct mac_conf_struct{ + mac_header mac; + ip_header ip; + udp_header udp; + u_int32_t npack; + u_int32_t lpack; + u_int32_t npad; + u_int32_t cdone; +} mac_conf; + +typedef struct tse_conf_struct{ + u_int32_t rev; //0x0 + u_int32_t scratch; + u_int32_t command_config; + u_int32_t mac_0; //0x3 + u_int32_t mac_1; + u_int32_t frm_length; + u_int32_t pause_quant; + u_int32_t rx_section_empty; //0x7 + u_int32_t rx_section_full; + u_int32_t tx_section_empty; + u_int32_t tx_section_full; + u_int32_t rx_almost_empty; //0xB + u_int32_t rx_almost_full; + u_int32_t tx_almost_empty; + u_int32_t tx_almost_full; + u_int32_t mdio_addr0; //0xF + u_int32_t mdio_addr1; +}tse_conf; + + + +int mapCSP0(void) { + printf("Mapping memory\n"); +#ifndef VIRTUAL + int fd; + fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + printf("\nCan't find /dev/mem!\n"); + return FAIL; + } + printf("/dev/mem opened\n"); + + CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + printf("\nCan't map memmory area!!\n"); + return FAIL; + } + printf("CSP0 mapped\n"); + +#endif +#ifdef VIRTUAL + CSP0BASE = malloc(MEM_SIZE); + printf("memory allocated\n"); +#endif +#ifdef SHAREDMEMORY + if ( (res=inism(SMSV))<0) { + printf("error attaching shared memory! %i",res); + return FAIL; + } +#endif + printf("CSPObase is 0x%x \n",CSP0BASE); + printf("CSPOBASE=from %08x to %x\n",CSP0BASE,CSP0BASE+MEM_SIZE); + + u_int32_t address; + address = FIFO_DATA_REG_OFF; + values=(u_int16_t*)(CSP0BASE+address*2); + printf("statusreg=%08x\n",bus_r(STATUS_REG)); + printf("\n\n"); + return OK; +} + +u_int16_t bus_r16(u_int32_t offset){ + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + return *ptr1; +} + +u_int16_t bus_w16(u_int32_t offset, u_int16_t data) { + volatile u_int16_t *ptr1; + ptr1=(u_int16_t*)(CSP0BASE+offset*2); + *ptr1=data; + return OK; +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_w16(u_int32_t ramType, int adc, int adcCh, int Ch, u_int16_t data) { + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Writing to addr:%x\n",adr); + return bus_w16(adr,data); +} + +/** ramType is DARK_IMAGE_REG or GAIN_IMAGE_REG */ +u_int16_t ram_r16(u_int32_t ramType, int adc, int adcCh, int Ch){ + unsigned int adr = (ramType | adc << 8 | adcCh << 5 | Ch ); + // printf("Reading from addr:%x\n",adr); + return bus_r16(adr); +} + +u_int32_t bus_w(u_int32_t offset, u_int32_t data) { + volatile u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + *ptr1=data; + + return OK; +} + + +u_int32_t bus_r(u_int32_t offset) { + volatile u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset*2); + return *ptr1; +} + + +int setPhaseShiftOnce(){ + u_int32_t addr, reg; + int i; + addr=MULTI_PURPOSE_REG; + reg=bus_r(addr); +#ifdef VERBOSE + printf("Multipurpose reg:%x\n",reg); +#endif + + //Checking if it is power on(negative number) + // if(((reg&0xFFFF0000)>>16)>0){ + //bus_w(addr,0x0); //clear the reg + + if(reg==0){ + printf("\nImplementing phase shift of %d\n",phase_shift); + for (i=1;i0) { + bus_w(PLL_CNTRL_REG, 1);//reset PLL + bus_w(PLL_CNTRL_REG, 0); + phase_shift=0; + for (i=0;i1) nc=d;// nc=161/d; + else return -1; + + if (nc>255) + return -1; + + int addr, addr1, addr0; + u_int32_t pat,pat1,pat0; + + addr= PLL_PARAM_REG; + addr0= PLL_PARAM_OUT_REG; + addr1=PLL_CNTRL_REG; + pat1=0x10; + + + //write high count c0 +/* pat=(1<<12)|(7<<9)|nc; */ +/* bus_w(addr, pat); */ +/* bus_w(addr1, pat1); */ +/* bus_w(addr1, 0); */ +/* usleep (1000); */ +/* pat=bus_r(addr0); */ +/* bus_w(addr1, 0x4); */ +/* bus_w(addr1, 0); */ +/* pat=bus_r(addr0); */ +/* printf("M nominal count read %x (%d)\n",pat,(pat&0x1ff)); */ + + + + //write low count c0 + pat=(nc-1)|(4<<12)|(1<<9); + bus_w(addr, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + pat0=bus_r(PLL_PARAM_OUT_REG); + usleep (1000); + printf("C0 low count status %x\n",pat0); + + //write high count c0 + pat=(nc)|(4<<12)|(0<<9); + bus_w(addr, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + pat0=bus_r(PLL_PARAM_OUT_REG); + printf("C0 high count status %x\n",pat0); + usleep (1000); + + //write low count c1 + pat=(nc-1)|(5<<12)|(1<<9); + bus_w(addr, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + pat0=bus_r(PLL_PARAM_OUT_REG); + printf("C1 high count status %x\n",pat0); + usleep (1000); + + //write high count c1 + pat=(nc)|(5<<12)|(0<<9); + bus_w(addr, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + pat0=bus_r(PLL_PARAM_OUT_REG); + printf("C1 low count status %x\n",pat0); + usleep (1000); + + //reconfigure pll + pat1=0x8; + bus_w(addr1, pat1); + bus_w(addr1, 0); + pat0=bus_r(PLL_PARAM_OUT_REG); + printf("configure status %d\n",pat0); + sleep (1); + printf("finish status %x\n",pat0); + + + bus_w(PLL_CNTRL_REG, 1); //reset PLL + bus_w(PLL_CNTRL_REG, 0); + + return 0; +} + +u_int32_t getClockDivider() { + int addr, addr1, addr0; + u_int32_t pat,pat1; + + addr0= PLL_PARAM_REG; + addr= PLL_PARAM_OUT_REG; + addr1=PLL_CNTRL_REG; + pat1=0x4; + + + //write low count c0 + pat=(4<<12)|(1<<9); + bus_w(addr0, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + usleep (1000); + pat=bus_r(addr); + printf("C0 low count read %x (%d)\n",pat,(pat&0xff)); + + //write high count c0 + pat=(4<<12)|(0<<9); + bus_w(addr0, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + usleep (1000); + pat=bus_r(addr); + printf("C0 high count read %x (%d)\n",pat,(pat&0xff)); + + + //write low count c1 + pat=(5<<12)|(1<<9); + bus_w(addr0, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + usleep (1000); + pat=bus_r(addr); + printf("C1 low count read %x (%d)\n",pat,(pat&0xff)); + + //write high count c1 + pat=(5<<12)|(0<<9); + bus_w(addr0, pat); + bus_w(addr1, pat1); + bus_w(addr1, 0); + usleep (1000); + pat=bus_r(addr); + printf("C1 high count read %x (%d)\n",pat,(pat&0xff)); + + + return (pat&0xff); + +/* //write low count c0 */ +/* pat=(0<<12)|(7<<9); */ +/* bus_w(addr0, pat); */ +/* bus_w(addr1, pat1); */ +/* bus_w(addr1, 0); */ +/* usleep (1000); */ +/* pat=bus_r(addr); */ +/* printf("N nominal count read %x (%d)\n",pat,pat&0x1ff); */ + +/* //write high count c0 */ +/* pat=(1<<12)|(7<<9); */ +/* bus_w(addr0, pat); */ +/* bus_w(addr1, pat1); */ +/* bus_w(addr1, 0); */ +/* usleep (1000); */ +/* pat=bus_r(addr); */ +/* printf("M nominal count read %x (%d)\n",pat,(pat&0x1ff)); */ + + + +/* if ((pat&0x1ff)!=0) */ +/* return 161/(pat&0x1ff); */ +/* else */ +/* return -1; */ +} + +u_int32_t setSetLength(int d) { + return 0; +} + +u_int32_t getSetLength() { + return 0; +} + +u_int32_t setOversampling(int d) { + + if (d>=0 && d<=255) + bus_w(OVERSAMPLING_REG, d); + + return bus_r(OVERSAMPLING_REG); +} + + +u_int32_t setWaitStates(int d1) { + return 0; +} + +u_int32_t getWaitStates() { + return 0; +} + + +u_int32_t setTotClockDivider(int d) { + return 0; +} + +u_int32_t getTotClockDivider() { + return 0; +} + + +u_int32_t setTotDutyCycle(int d) { + return 0; +} + +u_int32_t getTotDutyCycle() { + return 0; +} + + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode) { + + //int modes[]={EXT_SIG_OFF, EXT_GATE_IN_ACTIVEHIGH, EXT_GATE_IN_ACTIVELOW,EXT_TRIG_IN_RISING,EXT_TRIG_IN_FALLING,EXT_RO_TRIG_IN_RISING, EXT_RO_TRIG_IN_FALLING,EXT_GATE_OUT_ACTIVEHIGH, EXT_GATE_OUT_ACTIVELOW, EXT_TRIG_OUT_RISING, EXT_TRIG_OUT_FALLING, EXT_RO_TRIG_OUT_RISING, EXT_RO_TRIG_OUT_FALLING}; + // int off=d*SIGNAL_OFFSET; + + u_int32_t c; + c=bus_r(EXT_SIGNAL_REG); + + if (d>=0 && d<4) { + signals[d]=mode; +#ifdef VERBOSE + printf("settings signal variable number %d to value %04x\n", d, signals[d]); +#endif + + // if output signal, set it! + + switch (mode) { + case GATE_IN_ACTIVE_HIGH: + case GATE_IN_ACTIVE_LOW: + if (timingMode==GATE_FIX_NUMBER || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case TRIGGER_IN_RISING_EDGE: + case TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_EXPOSURE || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case RO_TRIGGER_IN_RISING_EDGE: + case RO_TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_READOUT) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case MASTER_SLAVE_SYNCHRONIZATION: + setSynchronization(syncMode); + break; + default: + setFPGASignal(d,mode); + break; + } + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + } + + +// if (mode<=RO_TRIGGER_OUT_FALLING_EDGE && mode>=0) +// bus_w(EXT_SIGNAL_REG,((modes[mode])<=0) { +#ifdef VERBOSE + printf("writing signal register number %d mode %04x\n",d, modes[mode]); +#endif + bus_w(EXT_SIGNAL_REG,((modes[mode])<>off); + + if (mode=0 && d<4) { +#ifdef VERBOSE + printf("gettings signal variable number %d value %04x\n", d, signals[d]); +#endif + return signals[d]; + } else + return -1; + + +} + + +int getFPGASignal(int d) { + + int modes[]={SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW,TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE,RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE,RO_TRIGGER_OUT_FALLING_EDGE}; + + int off=d*SIGNAL_OFFSET; + int mode=((bus_r(EXT_SIGNAL_REG)&(SIGNAL_MASK<>off); + + if (mode<=RO_TRIGGER_OUT_FALLING_EDGE) { + if (modes[mode]!=SIGNAL_OFF && signals[d]!=MASTER_SLAVE_SYNCHRONIZATION) + signals[d]=modes[mode]; +#ifdef VERYVERBOSE + printf("gettings signal register number %d value %04x\n", d, modes[mode]); +#endif + return modes[mode]; + } else + return -1; + +} + + + + + +/* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; +*/ + + +int setTiming(int ti) { + + + int ret=GET_EXTERNAL_COMMUNICATION_MODE; + + int g=-1, t=-1, rot=-1; + + int i; + + switch (ti) { + case AUTO_TIMING: + timingMode=ti; + // disable all gates/triggers in except if used for master/slave synchronization + for (i=0; i<4; i++) { + if (getFPGASignal(i)>0 && getFPGASignal(i)=0 && t>=0 && rot<0) { + ret=GATE_WITH_START_TRIGGER; + } else if (g<0 && t>=0 && rot<0) { + ret=TRIGGER_EXPOSURE; + } else if (g>=0 && t<0 && rot<0) { + ret=GATE_FIX_NUMBER; + } else if (g<0 && t<0 && rot>0) { + ret=TRIGGER_READOUT; + } else if (g<0 && t<0 && rot<0) { + ret=AUTO_TIMING; + } + + // timingMode=ret; + + return ret; + +} + + + +int setConfigurationRegister(int d) { +#ifdef VERBOSE + printf("Setting configuration register to %x",d); +#endif + if (d>=0) { + bus_w(CONFIG_REG,d); + } +#ifdef VERBOSE + printf("configuration register is %x", bus_r(CONFIG_REG)); +#endif + return bus_r(CONFIG_REG); +} + +int setToT(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting ToT to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: ToT is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|TOT_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~TOT_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("ToT is %x\n", reg); +#endif + if (reg&TOT_ENABLE_BIT) + return 1; + else + return 0; +} + +int setContinousReadOut(int d) { + //int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting Continous readout to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: Continous readout is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|CONT_RO_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~CONT_RO_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Continous readout is %x\n", reg); +#endif + if (reg&CONT_RO_ENABLE_BIT) + return 1; + else + return 0; +} + + +int startReceiver(int start) { + u_int32_t addr=CONFIG_REG; +#ifdef VERBOSE + if(start) + printf("Setting up detector to send to Receiver\n"); + else + printf("Setting up detector to send to CPU\n"); +#endif + int reg=bus_r(addr); + //for start recever, write 0 and for stop, write 1 + if (!start) + bus_w(CONFIG_REG,reg|CPU_OR_RECEIVER_BIT); + else + bus_w(CONFIG_REG,reg&(~CPU_OR_RECEIVER_BIT)); + + reg=bus_r(addr); +//#ifdef VERBOSE + printf("Config Reg %x\n", reg); +//#endif + int d =reg&CPU_OR_RECEIVER_BIT; + if(d!=0) d=1; + if(d!=start) + return OK; + else + return FAIL; +} + + +u_int64_t getDetectorNumber() { + char output[255],mac[255]=""; + u_int64_t res=0; + FILE* sysFile = popen("ifconfig eth0 | grep HWaddr | cut -d \" \" -f 11", "r"); + fgets(output, sizeof(output), sysFile); + pclose(sysFile); + //getting rid of ":" + char * pch; + pch = strtok (output,":"); + while (pch != NULL){ + strcat(mac,pch); + pch = strtok (NULL, ":"); + } + sscanf(mac,"%llx",&res); + return res; +} + +u_int32_t getFirmwareVersion() { + return bus_r(FPGA_VERSION_REG); +} + +u_int32_t getFirmwareSVNVersion(){ + return bus_r(FPGA_SVN_REG); +} + + +// for fpga test +u_int32_t testFpga(void) { + printf("Testing FPGA:\n"); + volatile u_int32_t val,addr,val2; + int result=OK,i; + //fixed pattern + val=bus_r(FIX_PATT_REG); + if (val==FIXED_PATT_VAL) { + printf("fixed pattern ok!! %08x\n",val); + } else { + printf("fixed pattern wrong!! %08x\n",val); + result=FAIL; + } + + //dummy register + addr = DUMMY_REG; + for(i=0;i<1000000;i++) + { + val=0x5A5A5A5A-i; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x5A5A5A5A-i) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of %x \n",i,val,0x5A5A5A5A-i); + result=FAIL; + } + val=(i+(i<<10)+(i<<20)); + bus_w(addr, val); + val2=bus_r(addr); + if (val2!=val) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! read %x instead of %x.\n",i,val2,val); + result=FAIL; + } + val=0x0F0F0F0F; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0x0F0F0F0F) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0x0F0F0F0F \n",i,val); + result=FAIL; + } + val=0xF0F0F0F0; + bus_w(addr, val); + val=bus_r(addr); + if (val!=0xF0F0F0F0) { + printf("ATTEMPT:%d:\tFPGA dummy register wrong!! %x instead of 0xF0F0F0F0 \n\n",i,val); + result=FAIL; + } + } + if(result==OK) + { + printf("----------------------------------------------------------------------------------------------"); + printf("\nATTEMPT 1000000: FPGA DUMMY REGISTER OK!!!\n"); + printf("----------------------------------------------------------------------------------------------"); + } + printf("\n"); + return result; +} + + +// for fpga test +u_int32_t testRAM(void) { + int result=OK; + int i=0; + allocateRAM(); + // while(i<100000) { + memcpy(ram_values, values, dataBytes); + printf ("Testing RAM:\t%d: copied fifo %x to memory %x size %d\n",i++, (unsigned int)(values), (unsigned int)(ram_values), dataBytes); + // } + return result; +} + +int getNModBoard() { + return nModX; +} + +int setNMod(int n) { + return nModX; +} + + +// fifo test +int testFifos(void) { + printf("Fifo test not implemented!\n"); + bus_w16(CONTROL_REG, START_FIFOTEST_BIT); + bus_w16(CONTROL_REG, 0x0); + return OK; +} + + + +// program dacq settings + +int64_t set64BitReg(int64_t value, int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + if (value!=-1) { + vLSB=value&(0xffffffff); + bus_w(aLSB,vLSB); + v64=value>> 32; + vMSB=v64&(0xffffffff); + bus_w(aMSB,vMSB); + } + return get64BitReg(aLSB, aMSB); + +} + +int64_t get64BitReg(int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + vLSB=bus_r(aLSB); + vMSB=bus_r(aMSB); + v64=vMSB; + v64=(v64<<32) | vLSB; + + printf("reg64(%x,%x) %x %x %llx\n", aLSB, aMSB, vLSB, vMSB, v64); + + return v64; +} + +int64_t setFrames(int64_t value){ + return set64BitReg(value, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); +} + +int64_t getFrames(){ + printf("gf"); + return get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); +} + +int64_t setExposureTime(int64_t value){ + /* time is in ns */ + if (value!=-1) + value*=(1E-9*CLK_FREQ); + return set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getExposureTime(){ + return get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setGates(int64_t value){ + return set64BitReg(value, SET_GATES_LSB_REG, SET_GATES_MSB_REG); +} + +int64_t getGates(){ + return get64BitReg(GET_GATES_LSB_REG, GET_GATES_MSB_REG); +} + +int64_t setPeriod(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + + + + return set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getPeriod(){ + return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setDelay(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + return set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getDelay(){ + return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setTrains(int64_t value){ + return set64BitReg(value, SET_TRAINS_LSB_REG, SET_TRAINS_MSB_REG); +} + +int64_t getTrains(){ + return get64BitReg(GET_TRAINS_LSB_REG, GET_TRAINS_MSB_REG); +} + + +int64_t setProbes(int64_t value){ + return 0; +} + + +int64_t setProgress() { + + //????? eventually call after setting the registers + +return 0; + +} + + +int64_t getProgress() { + + + //should be done in firmware!!!! + + return 0; + +} + +int64_t getActualTime(){ + return get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getMeasurementTime(){ + int64_t v=get64BitReg(GET_MEASUREMENT_TIME_LSB_REG, GET_MEASUREMENT_TIME_MSB_REG); + int64_t mask=0x8000000000000000; + if (v & mask ) { +#ifdef VERBOSE + printf("no measurement time left\n"); +#endif + return -1E+9; + } else + return v/(1E-9*CLK_FREQ); +} + + + + +int loadImage(int index, short int ImageVals[]){ + u_int32_t address; + switch (index) { + case DARK_IMAGE : + address = DARK_IMAGE_REG; + break; + case GAIN_IMAGE : + address = GAIN_IMAGE_REG; + break; + } + volatile u_int16_t *ptr; + ptr=(u_int16_t*)(CSP0BASE+address*2); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,ImageVals[i]); +#endif + memcpy(ptr,ImageVals ,dataBytes); +#ifdef VERBOSE + printf("\nLoaded x%08x address with image of index %d\n",(unsigned int)(ptr),index); +#endif + return OK; +} + + + +int64_t getProbes(){ + return 0; +} + + +int setDACRegister(int idac, int val, int imod) { + u_int32_t addr, reg, mask; + int off; +#ifdef VERBOSE + if(val==-1) + printf("Getting dac register%d module %d\n",idac,imod); + else + printf("Setting dac register %d module %d to %d\n",idac,imod,val); +#endif + + switch(idac){ + case 0: + case 1: + case 2: + addr=MOD_DACS1_REG; + break; + case 3: + case 4: + case 5: + addr=MOD_DACS2_REG; + break; + case 6: + case 7: + addr=MOD_DACS3_REG; + break; + default: + printf("weird idac value %d\n",idac); + return -1; + break; + } + //saving only the msb + val=val>>2; + + off=(idac%3)*10; + mask=~((0x3ff)<=0 && val>off)&0x3ff; + //since we saved only the msb + val=val<<2; + + //val=(bus_r(addr)>>off)&0x3ff; + + +#ifdef VERBOSE + printf("Dac %d module %d register is %d\n\n",idac,imod,val); +#endif + return val; +} + + +int getTemperature(int tempSensor, int imod){ + int val; + imod=0;//ignoring more than 1 mod for now + int i,j,repeats=6; + u_int32_t tempVal=0; +#ifdef VERBOSE + char cTempSensor[2][100]={"ADCs/ASICs","VRs/FPGAs"}; + printf("Getting Temperature of module:%d for the %s for tempsensor:%d\n",imod,cTempSensor[tempSensor],tempSensor); +#endif + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + bus_w(TEMP_IN_REG,((T1_CLK_BIT)&~(T1_CS_BIT))|(T2_CLK_BIT));//high clk low cs + + for(i=0;i<20;i++) { + //repeats is number of register writes for delay + for(j=0;j>1);//fpga + } + } + + bus_w(TEMP_IN_REG,(T1_CLK_BIT)|(T1_CS_BIT)|(T2_CLK_BIT)|(T2_CS_BIT));//standby + val=((int)tempVal)/4.0; + +#ifdef VERBOSE + printf("Temperature of module:%d for the %s is %.2fC\n",imod,cTempSensor[tempSensor],val); +#endif + return val; +} + + + +int initHighVoltage(int val, int imod){ +#ifdef VERBOSE + printf("Setting/Getting High Voltage of module:%d with val:%d\n",imod,val); +#endif + volatile u_int32_t addr=HV_REG; + int writeVal,writeVal2; + switch(val){ + case -1: break; + case 0: writeVal=0x0; writeVal2=0x0; break; + case 90: writeVal=0x0; writeVal2=0x1; break; + case 110:writeVal=0x2; writeVal2=0x3; break; + case 120:writeVal=0x4; writeVal2=0x5; break; + case 150:writeVal=0x6; writeVal2=0x7; break; + case 180:writeVal=0x8; writeVal2=0x9; break; + case 200:writeVal=0xA; writeVal2=0xB; break; + default :printf("Invalid voltage\n");return -2;break; + } + //to set value + if(val!=-1){ + //set value to converted value + bus_w(addr,writeVal); + bus_w(addr,writeVal2); +#ifdef VERBOSE + printf("Value sent is %d and then %d\n",writeVal,writeVal2); +#endif + } + //read value and return the converted value + val=bus_r(addr); +#ifdef VERBOSE + printf("Value read from reg is %d\n",val); +#endif + switch(val){ + case 0x0:val=0;break; + case 0x1:val=90;break; + case 0x3:val=110;break; + case 0x5:val=120;break; + case 0x7:val=150;break; + case 0x9:val=180;break; + case 0xB:val=200;break; + default:printf("Weird value read:%d\n",val);return -3;break; + } +#ifdef VERBOSE + printf("High voltage of module:%d is %d\n",imod,val); +#endif + return val; +} + + + +int initConfGain(int isettings,int val,int imod){ + int retval; + u_int32_t addr=GAIN_REG; + + if(val!=-1){ +#ifdef VERBOSE + printf("Setting Gain of module:%d with val:%d\n",imod,val); +#endif + bus_w(addr,((val<>SETTINGS_OFFSET); +#ifdef VERBOSE + printf("Settings read from reg is %d\n",retval); +#endif + if((isettings!=-1)&&(retval!=isettings)){ + printf("\n\nSettings r\n\n"); + return -1; + } + + return retval; +} + + + +int setADC(int adc){ + int reg,nchips,mask,nchans; + + if(adc==-1) ROI_flag=0; + else ROI_flag=1; + + setDAQRegister();//token timing + cleanFifo();//adc sync + +/* if(adc==-1){*/ + //set packet size + ipPacketSize= DEFAULT_IP_PACKETSIZE; + udpPacketSize=DEFAULT_UDP_PACKETSIZE; + //set channel mask + nchips = NCHIP; + nchans = NCHANS; + mask = ACTIVE_ADC_MASK; + /* + //with moench module 1 adc -- NOT IMPLEMENTED + else{ + ipPacketSize= ADC1_IP_PACKETSIZE; + udpPacketSize=ADC1_UDP_PACKETSIZE; + //set channel mask + nchips = NCHIPS_PER_ADC; + nchans = GOTTHARDNCHAN; + mask = 1<mac.mac_dest_mac1 =((macad>>(8*5))&0xFF);// 0x00; //pc7060 + mac_conf_regs->mac.mac_dest_mac2 =((macad>>(8*4))&0xFF);// 0x19; //pc7060 + mac_conf_regs->mac.mac_dest_mac3 =((macad>>(8*3))&0xFF);// 0x99; //pc7060 + mac_conf_regs->mac.mac_dest_mac4 =((macad>>(8*2))&0xFF);// 0x24; //pc7060 + mac_conf_regs->mac.mac_dest_mac5 =((macad>>(8*1))&0xFF);// 0xEB; //pc7060 + mac_conf_regs->mac.mac_dest_mac6 =((macad>>(8*0))&0xFF);// 0xEE; //pc7060 + + /* + mac_conf_regs->mac.mac_src_mac1 = 0x00; + mac_conf_regs->mac.mac_src_mac2 = 0xAA; + mac_conf_regs->mac.mac_src_mac3 = 0xBB; + mac_conf_regs->mac.mac_src_mac4 = 0xCC; + mac_conf_regs->mac.mac_src_mac5 = 0xDD; + mac_conf_regs->mac.mac_src_mac6 = 0xEE; + */ + mac_conf_regs->mac.mac_src_mac1 =((detectormacad>>(8*5))&0xFF); + mac_conf_regs->mac.mac_src_mac2 =((detectormacad>>(8*4))&0xFF); + mac_conf_regs->mac.mac_src_mac3 =((detectormacad>>(8*3))&0xFF); + mac_conf_regs->mac.mac_src_mac4 =((detectormacad>>(8*2))&0xFF); + mac_conf_regs->mac.mac_src_mac5 =((detectormacad>>(8*1))&0xFF); + mac_conf_regs->mac.mac_src_mac6 =((detectormacad>>(8*0))&0xFF); + mac_conf_regs->mac.mac_ether_type = 0x0800; //ipv4 + + + + mac_conf_regs->ip.ip_ver = 0x4; + mac_conf_regs->ip.ip_ihl = 0x5; + mac_conf_regs->ip.ip_tos = 0x0; + mac_conf_regs->ip.ip_len = ipPacketSize;//0x0522; // was 0x0526; + mac_conf_regs->ip.ip_ident = 0x0000; + mac_conf_regs->ip.ip_flag = 0x2; + mac_conf_regs->ip.ip_offset = 0x00; + mac_conf_regs->ip.ip_ttl = 0x70; + mac_conf_regs->ip.ip_protocol = 0x11; + mac_conf_regs->ip.ip_chksum = 0x0000 ; //6E42 now is automatically computed + mac_conf_regs->ip.ip_sourceip = detipad; //0x8181CA2E;129.129.202.46 + mac_conf_regs->ip.ip_destip = ipad; //CA57 + + //#ifdef VERBOSE + printf("mac_dest:%llx %x:%x:%x:%x:%x:%x\n", + macad, + mac_conf_regs->mac.mac_dest_mac1, + mac_conf_regs->mac.mac_dest_mac2, + mac_conf_regs->mac.mac_dest_mac3, + mac_conf_regs->mac.mac_dest_mac4, + mac_conf_regs->mac.mac_dest_mac5, + mac_conf_regs->mac.mac_dest_mac6); + printf("mac_src:%llx %x:%x:%x:%x:%x:%x\n", + detectormacad, + mac_conf_regs->mac.mac_src_mac1, + mac_conf_regs->mac.mac_src_mac2, + mac_conf_regs->mac.mac_src_mac3, + mac_conf_regs->mac.mac_src_mac4, + mac_conf_regs->mac.mac_src_mac5, + mac_conf_regs->mac.mac_src_mac6); + printf("ip_ttl:%x\n",mac_conf_regs->ip.ip_ttl); + printf("det_ip: %x %x\n",detipad, mac_conf_regs->ip.ip_sourceip); + printf("dest_ip: %x %x\n",ipad, mac_conf_regs->ip.ip_destip); + + //#endif + + //checksum + count=sizeof(mac_conf_regs->ip); + addr=&(mac_conf_regs->ip); + while( count > 1 ) { + sum += *addr++; + count -= 2; + } + if( count > 0 ) sum += *addr; // Add left-over byte, if any + while (sum>>16) sum = (sum & 0xffff) + (sum >> 16);// Fold 32-bit sum to 16 bits + checksum = (~sum)&0xffff; + mac_conf_regs->ip.ip_chksum = checksum; + //#ifdef VERBOSE + printf("IP header checksum is 0x%x s\n",(unsigned int)(checksum)); + //#endif + + mac_conf_regs->udp.udp_srcport = 0xE185; + mac_conf_regs->udp.udp_destport = udpport;//0xC351; + mac_conf_regs->udp.udp_len = udpPacketSize;//0x050E; //was 0x0512; + mac_conf_regs->udp.udp_chksum = 0x0000; + +#ifdef VERBOSE + printf("Configuring TSE\n"); +#endif + tse_conf_regs->rev = 0xA00; + tse_conf_regs->scratch = 0xCCCCCCCC; + tse_conf_regs->command_config = 0xB; + tse_conf_regs->mac_0 = 0x17231C00; + tse_conf_regs->mac_1 = 0xCB4A; + tse_conf_regs->frm_length = 0x5DC; //max frame length (1500 bytes) (was 0x41C) + tse_conf_regs->pause_quant = 0x0; + tse_conf_regs->rx_section_empty = 0x7F0; + tse_conf_regs->rx_section_full = 0x10; + tse_conf_regs->tx_section_empty = 0x3F8; //was 0x7F0; + tse_conf_regs->tx_section_full = 0x16; + tse_conf_regs->rx_almost_empty = 0x8; + tse_conf_regs->rx_almost_full = 0x8; + tse_conf_regs->tx_almost_empty = 0x8; + tse_conf_regs->tx_almost_full = 0x3; + tse_conf_regs->mdio_addr0 = 0x12; + tse_conf_regs->mdio_addr1 = 0x0; + + mac_conf_regs->cdone = 0xFFFFFFFF; + + + if(ival) + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|WRITE_BACK_BIT|DIGITAL_TEST_BIT)); //0x2840,write shadow regs.. + else + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|WRITE_BACK_BIT)); //0x2840,write shadow regs.. + + val=bus_r(addrr); +#ifdef VERBOSE + printf("Value read from Multi-purpose Reg:%x\n",val); +#endif + // if(val!=0x2840) return -1; + + usleep(100000); + + if(ival) + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|SW1_BIT|DIGITAL_TEST_BIT)); //0x2820,write shadow regs.. + else + bus_w(addrr,(INT_RSTN_BIT|ENET_RESETN_BIT|SW1_BIT)); //0x2820,write shadow regs.. + + val=bus_r(addrr); +#ifdef VERBOSE + printf("Value read from Multi-purpose Reg:%x\n",val); +#endif + // if(val!=0x2820) return -1; + + + + + return adcConfigured; +} + + +int getAdcConfigured(){ + return adcConfigured; +} + +u_int32_t runBusy(void) { + u_int32_t s = bus_r(STATUS_REG) & 1; +#ifdef VERBOSE + printf("status %04x\n",s); +#endif + return s; +} + +u_int32_t dataPresent(void) { + return bus_r(LOOK_AT_ME_REG); +} + +u_int32_t runState(void) { + int s=bus_r(STATUS_REG); +#ifdef SHAREDMEMORY + if (s&RUN_BUSY_BIT) + write_status_sm("Running"); + else + write_status_sm("Stopped"); +#endif +#ifdef VERBOSE + printf("status %04x\n",s); +#endif + +/* if (s==0x62001) + exit(-1);*/ + return s; +} + + +// State Machine + +int startStateMachine(){ +int i; +//#ifdef VERBOSE + printf("*******Starting State Machine*******\n"); +//#endif + cleanFifo(); + // fifoReset(); + now_ptr=(char*)ram_values; +#ifdef SHAREDMEMORY + write_stop_sm(0); + write_status_sm("Started"); +#endif + + + for(i=0;i<100;i++){ + //start state machine + bus_w16(CONTROL_REG, START_ACQ_BIT | START_EXPOSURE_BIT); + bus_w16(CONTROL_REG, 0x0); + //verify + if(bus_r(STATUS_REG) & RUN_BUSY_BIT) + break; + else + usleep(5000); + } + if(i!=0) + printf("tried to start state machine %d times\n",i); + if(i==100){ + printf("\n***********COULD NOT START STATE MACHINE***************\n"); + return FAIL; + } + + printf("statusreg=%08x\n",bus_r(STATUS_REG)); + return OK; +} + + + + +int stopStateMachine(){ + int i; +//#ifdef VERBOSE + printf("*******Stopping State Machine*******\n"); +//#endif +#ifdef SHAREDMEMORY + write_stop_sm(1); + write_status_sm("Stopped"); +#endif + for(i=0;i<100;i++){ + //stop state machine + bus_w16(CONTROL_REG, STOP_ACQ_BIT); + bus_w16(CONTROL_REG, 0x0); + usleep(5000); + //verify + if(!(bus_r(STATUS_REG)&RUNMACHINE_BUSY_BIT)) + break; + } + if(i!=0) + printf("tried to stop state machine %d times\n",i); + if(i==100){ + printf("\n***********COULD NOT STOP STATE MACHINE***************\n"); + return FAIL; + } + +/* + usleep(5000); + // if (!runBusy()) + if(!(bus_r(STATUS_REG)&RUNMACHINE_BUSY_BIT)) + return OK; + else + return FAIL; + */ + printf("statusreg=%08x\n",bus_r(STATUS_REG)); + return OK; +} + + +int startReadOut(){ + u_int32_t status; +#ifdef VERBOSE + printf("Starting State Machine Readout\n"); +#endif + status=bus_r(STATUS_REG)&RUN_BUSY_BIT; +#ifdef DEBUG + printf("State machine status is %08x\n",bus_r(STATUS_REG)); +#endif + bus_w16(CONTROL_REG, START_ACQ_BIT |START_READOUT_BIT); // start readout + bus_w16(CONTROL_REG, 0x0); + return OK; +} + + +// fifo routines + +u_int32_t fifoReset(void) { + return -1; +} + + +u_int32_t setNBits(u_int32_t n) { + return -1; +} + +u_int32_t getNBits(){ + return -1; +} + + +u_int32_t fifoReadCounter(int fifonum){ + return -1; +} + +u_int32_t fifoReadStatus() +{ + // reads from the global status register + + return bus_r(STATUS_REG)&(SOME_FIFO_FULL_BIT | ALL_FIFO_EMPTY_BIT); +} + +u_int32_t fifo_full(void) +{ + // checks fifo empty flag returns 1 if fifo is empty + // otherwise 0 + return bus_r(STATUS_REG)&SOME_FIFO_FULL_BIT; +} + + +u_int32_t* fifo_read_event() +{ + + int i=0; + +#ifdef VIRTUAL + return NULL; +#endif + +#ifdef VERBOSE + printf("before looping\n"); +#endif + volatile u_int32_t t = bus_r(LOOK_AT_ME_REG); + +#ifdef VERBOSE + printf("lookatmereg=x%x\n",t); +#endif +/* + while ((t&0x1)==0) + { + t = bus_r(LOOK_AT_ME_REG); + if (!runBusy()){ + return NULL; + } + } +*/ + + while((t&0x1)==0) { +#ifdef VERYVERBOSE + printf("before readout %08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); +#endif +#ifdef VERYVERBOSE + printf("look at me reg:%08x\n",bus_r(LOOK_AT_ME_REG)); +#endif + if (runBusy()==0) { + t = bus_r(LOOK_AT_ME_REG); +#ifdef VERYVERBOSE + printf("status should be idle!..look at me reg:%08x\n",bus_r(LOOK_AT_ME_REG)); +#endif + if ((t&0x1)==0) { +#ifdef VERBOSE + printf("no frame found - exiting\n"); + printf("%08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); +#endif +#ifdef VERYVERBOSE + printf("returning null\n"); +#endif + printf("lookatmereg=x%x\n",t); + return NULL; + } else { +#ifdef VERBOSE + printf("no frame found %x status %x\n", bus_r(LOOK_AT_ME_REG),runState()); +#endif + break; + } + } + t = bus_r(LOOK_AT_ME_REG); +#ifdef VERYVERBOSE + printf("before starting while loop again: look at me reg:%08x\n\n",bus_r(LOOK_AT_ME_REG)); +#endif + if (i%1000==0) + printf("%08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); + i++; + } +#ifdef VERYVERBOSE + printf(" out of while loop!\n"); +#endif +#ifdef VERYVERBOSE + printf("before readout %08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); +#endif + + dma_memcpy(now_ptr,values ,dataBytes); + + +#ifdef VERYVERBOSE + int a; + for (a=0;a<8; a=a+2) + printf("\n%d %d: x%04x x%04x ",a+1,a,*(now_ptr+a+1),*(now_ptr+a) ); + for (a=2554;a<2560; a=a+2) + printf("\n%d %d: x%04x x%04x ",a+1,a,*(now_ptr+a+1),*(now_ptr+a) ); + printf("********\n"); + //memcpy(now_ptr, values, dataBytes); +#endif +#ifdef VERYVERBOSE + printf("Copying to ptr %08x %d\n",(unsigned int)(now_ptr), dataBytes); + printf("after readout %08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); +#endif + + if (storeInRAM>0) { + now_ptr+=dataBytes; + } + printf("lookatmereg=x%x\n",t); + return ram_values; +} + + + +u_int32_t* decode_data(int *datain) +{ + u_int32_t *dataout; + // const char one=1; + const int bytesize=8; + char *ptr=(char*)datain; + //int nbits=dynamicRange; + int ipos=0, ichan=0;; + //int nch, boff=0; + int ibyte;//, ibit; + char iptr; + +#ifdef VERBOSE + printf("Decoding data for DR %d\n",dynamicRange); +#endif + dataout=malloc(nChans*nChips*nModX*4); + ichan=0; + switch (dynamicRange) { + case 1: + for (ibyte=0; ibyte>(ipos))&0x1; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibyte>(ipos*4))&0xf; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichan0) + storeInRAM=1; + else + storeInRAM=0; + return allocateRAM(); +} + + +int allocateRAM() { + size_t size; + u_int32_t nt, nf; + nt=setTrains(-1); + nf=setFrames(-1); + if (nt==0) nt=1; + if (nf==0) nf=1; + // ret=clearRAM(); + if (storeInRAM) { + size=dataBytes*nf*nt; + if (size>(23-i))&0x1)<> 8); + // printf("%i: %i %i\n",a, frame[a],v); + avg[a] += ((double)frame[a])/(double)frames; + //if(frame[a] == 8191) + // printf("ch %i: %u\n",a,frame[a]); + } + // printf("********\n"); + numberFrames++; + } + + //no more data or no data + else { + if(getFrames()>-2) { + dataret=FAIL; + printf("no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + + } else { + dataret=FINISHED; + printf("acquisition successfully finished\n"); + + } + printf("dataret %d\n",dataret); + } + } + + + + double nf = (double)numberFrames; + for(i =0; i < 1280; i++){ + adc = i / 256; + adcCh = (i - adc * 256) / 32; + Ch = i - adc * 256 - adcCh * 32; + adc--; + double v2 = avg[i]; + avg[i] = avg[i]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[i]; + printf("setting avg for channel %i(%i,%i,%i): %i (double= %f (%f))\t", i,adc,adcCh,Ch, v,avg[i],v2); + v=i*100; + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + + /*for(adc = 1; adc < 5; adc++){ + for(adcCh = 0; adcCh < 8; adcCh++){ + for(Ch=0 ; Ch < 32; Ch++){ + int channel = (adc+1) * 32 * 8 + adcCh * 32 + Ch; + double v2 = avg[channel]; + avg[channel] = avg[channel]/ ((double)numberFrames/(double)frames); + unsigned short v = (unsigned short)avg[channel]; + printf("setting avg for channel %i: %i (double= %f (%f))\t", channel, v,avg[channel],v2); + ram_w16(DARK_IMAGE_REG,adc,adcCh,Ch,v-4096); + if(ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch) != v-4096){ + printf("value is wrong (%i,%i,%i): %i \n",adc,adcCh,Ch, ram_r16(DARK_IMAGE_REG,adc,adcCh,Ch)); + } + } + } + }*/ + + + + printf("frames: %i\n",numberFrames); + printf("corrected avg by: %f\n",(double)numberFrames/(double)frames); + + printf("restoring previous condition\n"); + setFrames(framesBefore); + setPeriod(periodBefore); + + printf("---------------------------\n"); + return 0; +} + diff --git a/slsDetectorSoftware/moenchDetectorServer/firmware_funcs.h b/slsDetectorSoftware/moenchDetectorServer/firmware_funcs.h new file mode 100755 index 000000000..48918e428 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/firmware_funcs.h @@ -0,0 +1,179 @@ +#ifndef FIRMWARE_FUNCS_H +#define FIRMWARE_FUNCS_H + + +#include "sls_detector_defs.h" + + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +int mapCSP0(void); + +u_int16_t bus_r16(u_int32_t offset); +u_int16_t bus_w16(u_int32_t offset, u_int16_t data);//aldos function +u_int32_t bus_w(u_int32_t offset, u_int32_t data); +u_int32_t bus_r(u_int32_t offset); + +int setPhaseShiftOnce(); +int phaseStep(int st); +int cleanFifo(); +int setDAQRegister(); + +u_int32_t putout(char *s, int modnum); +u_int32_t readin(int modnum); +u_int32_t setClockDivider(int d); +u_int32_t getClockDivider(); +u_int32_t setSetLength(int d); +u_int32_t getSetLength(); +u_int32_t setWaitStates(int d); +u_int32_t getWaitStates(); +u_int32_t setTotClockDivider(int d); +u_int32_t getTotClockDivider(); +u_int32_t setTotDutyCycle(int d); +u_int32_t getTotDutyCycle(); +u_int32_t setOversampling(int d); + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode); +int getExtSignal(int d); + +u_int32_t setFPGASignal(int d, enum externalSignalFlag mode); +int getFPGASignal(int d); + +int setTiming(int t); + + +int setConfigurationRegister(int d); +int setToT(int d); +int setContinousReadOut(int d); +int startReceiver(int d); + +int setDACRegister(int idac, int val, int imod); + +int getTemperature(int tempSensor,int imod); +int initHighVoltage(int val,int imod); +int initConfGain(int isettings,int val,int imod); + +int setADC(int adc); +int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int ival, int udpport); +int getAdcConfigured(); + + +u_int64_t getDetectorNumber(); +u_int32_t getFirmwareVersion(); +int testFifos(void); +u_int32_t testFpga(void); +u_int32_t testRAM(void); +int testBus(void); +int setDigitalTestBit(int ival); + +int64_t set64BitReg(int64_t value, int aLSB, int aMSB); +int64_t get64BitReg(int aLSB, int aMSB); + +int64_t setFrames(int64_t value); +int64_t getFrames(); + +int64_t setExposureTime(int64_t value); +int64_t getExposureTime(); + +int64_t setGates(int64_t value); +int64_t getGates(); + +int64_t setDelay(int64_t value); +int64_t getDelay(); + +int64_t setPeriod(int64_t value); +int64_t getPeriod(); + +int64_t setTrains(int64_t value); +int64_t getTrains(); + +int64_t setProbes(int64_t value); +int64_t getProbes(); + +int64_t getProgress(); +int64_t setProgress(); + +int64_t getActualTime(); +int64_t getMeasurementTime(); + + +u_int32_t runBusy(void); +u_int32_t runState(void); +u_int32_t dataPresent(void); + + +int startStateMachine(); +int stopStateMachine(); +int startReadOut(); +u_int32_t fifoReset(void); +u_int32_t fifoReadCounter(int fifonum); +u_int32_t fifoReadStatus(); + + +u_int32_t fifo_full(void); + + + +u_int32_t* fifo_read_event(); +u_int32_t* decode_data(int* datain); +//u_int32_t move_data(u_int64_t* datain, u_int64_t* dataout); +int setDynamicRange(int dr); +int getDynamicRange(); +int getNModBoard(); +int setNMod(int n); +int setStoreInRAM(int b); +int allocateRAM(); +int clearRAM(); + + +int setMaster(int f); +int setSynchronization(int s); + +int loadImage(int index, short int ImageVals[]); +int readCounterBlock(int startACQ, short int CounterVals[]); +int resetCounterBlock(int startACQ); + +int calibratePedestal(int frames); + + + +/* + +u_int32_t setNBits(u_int32_t); +u_int32_t getNBits(); +*/ + +/* +//move to mcb_funcs? + +int readOutChan(int *val); +u_int32_t getModuleNumber(int modnum); +int testShiftIn(int imod); +int testShiftOut(int imod); +int testShiftStSel(int imod); +int testDataInOut(int num, int imod); +int testExtPulse(int imod); +int testExtPulseMux(int imod, int ow); +int testDataInOutMux(int imod, int ow, int num); +int testOutMux(int imod); +int testFpgaMux(int imod); +int calibration_sensor(int num, int *values, int *dacs) ; +int calibration_chip(int num, int *values, int *dacs); +*/ + + +#endif diff --git a/slsDetectorSoftware/moenchDetectorServer/gitInfo.txt b/slsDetectorSoftware/moenchDetectorServer/gitInfo.txt new file mode 100644 index 000000000..2fc4e3520 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/gitInfo.txt @@ -0,0 +1,9 @@ +Path: slsDetectorsPackage/slsDetectorSoftware/moenchDetectorServer +URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git/moenchDetectorServer +Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git +Repsitory UUID: 8aceb5d4b0ca6bd95a11b53e7a799b463b92d51b +Revision: 80 +Branch: developer +Last Changed Author: Dhanya_Maliakal +Last Changed Rev: 334 +Last Changed Date: 2016-08-12 11:08:03 +0200 diff --git a/slsDetectorSoftware/moenchDetectorServer/gitInfoMoench.h b/slsDetectorSoftware/moenchDetectorServer/gitInfoMoench.h new file mode 100644 index 000000000..13579414d --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/gitInfoMoench.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "git@git.psi.ch:sls_detectors_software/sls_detector_software.git/moenchDetectorServer" +//#define SVNREPPATH "" +#define SVNREPUUID "8aceb5d4b0ca6bd95a11b53e7a799b463b92d51b" +//#define SVNREV 0x334 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "Dhanya_Maliakal" +#define SVNREV 0x334 +#define SVNDATE 0x20160812 +// diff --git a/slsDetectorSoftware/moenchDetectorServer/gitInfoMoenchTmp.h b/slsDetectorSoftware/moenchDetectorServer/gitInfoMoenchTmp.h new file mode 100644 index 000000000..58e48f497 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/gitInfoMoenchTmp.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "" +//#define SVNREPPATH "" +#define SVNREPUUID "" +//#define SVNREV "" +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "" +#define SVNREV "" +#define SVNDATE "" +// diff --git a/slsDetectorSoftware/moenchDetectorServer/mcb_funcs.c b/slsDetectorSoftware/moenchDetectorServer/mcb_funcs.c new file mode 100755 index 000000000..1db487a31 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/mcb_funcs.c @@ -0,0 +1,2528 @@ +#ifdef MCB_FUNCS + +#include +#include +#include +#include +#include +#include "registers_m.h" + +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" + + +/* global variables */ +#undef DEBUG +#undef DEBUGOUT + +extern int nModX; +//extern int dataBytes; +extern int dynamicRange; +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +enum detectorSettings thisSettings; + +int sChan, sChip, sMod, sDac, sAdc; +const int allSelected=-2; +const int noneSelected=-1; + + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +int *detectorDacs=NULL; +int *detectorAdcs=NULL; +//int numberOfProbes; + +ROI rois[MAX_ROIS]; +int nROI=0; + + +int initDetector() { + + int imod; + // sls_detector_module *myModule; + int n=getNModBoard(); + nModX=n; + +#ifdef VERBOSE + printf("Board is for %d modules\n",n); +#endif + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorChips=malloc(n*NCHIP*sizeof(int)); + detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); + detectorDacs=malloc(n*NDAC*sizeof(int)); + detectorAdcs=malloc(n*NADC*sizeof(int)); +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",(unsigned int)(detectorModules), (unsigned int)(detectorModules+n)); + printf("chips from 0x%x to 0x%x\n",(unsigned int)(detectorChips), (unsigned int)(detectorChips+n*NCHIP)); + printf("chans from 0x%x to 0x%x\n",(unsigned int)(detectorChans), (unsigned int)(detectorChans+n*NCHIP*NCHAN)); + printf("dacs from 0x%x to 0x%x\n",(unsigned int)(detectorDacs), (unsigned int)(detectorDacs+n*NDAC)); + printf("adcs from 0x%x to 0x%x\n",(unsigned int)(detectorAdcs), (unsigned int)(detectorAdcs+n*NADC)); +#endif + for (imod=0; imoddacs=detectorDacs+imod*NDAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*NADC; + (detectorModules+imod)->chipregs=detectorChips+imod*NCHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*NCHIP*NCHAN; + (detectorModules+imod)->ndac=NDAC; + (detectorModules+imod)->nadc=NADC; + (detectorModules+imod)->nchip=NCHIP; + (detectorModules+imod)->nchan=NCHIP*NCHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + + /* + setCSregister(ALLMOD); //commented out by dhanya + setSSregister(ALLMOD); + counterClear(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + */ + + /* initialize dynamic range etc. */ + /* dynamicRange=getDynamicRange(); //always 16 not required commented out + nModX=setNMod(-1);*/ + + //dataBytes=nModX*NCHIP*NCHAN*4; + // dynamicRange=32; + // initChip(0, 0,ALLMOD); + //nModX=n; + // + allocateRAM(); + + + return OK; +} + + + + +int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) { + destChan->chan=srcChan->chan; + destChan->chip=srcChan->chip; + destChan->module=srcChan->module; + destChan->reg=srcChan->reg; + return OK; +} + + +int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip) { + + int ichan; + int ret=OK; + if ((srcChip->nchan)>(destChip->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + + destChip->nchan=srcChip->nchan; + destChip->reg=srcChip->reg; + destChip->chip=srcChip->chip; + destChip->module=srcChip->module; + for (ichan=0; ichan<(srcChip->nchan); ichan++) { + *((destChip->chanregs)+ichan)=*((srcChip->chanregs)+ichan); + } + return ret; +} + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { + + int ichip, idac, ichan, iadc; + + int ret=OK; + +#ifdef VERBOSE + printf("Copying module %x to module %x\n",(unsigned int)(srcMod),(unsigned int)(destMod)); +#endif + + if (srcMod->module>=0) { +#ifdef VERBOSE + printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); +#endif + destMod->module=srcMod->module; + } + if (srcMod->serialnumber>=0){ +/* #ifdef VERBOSE */ +/* printf("Copying module serial number %x to module serial number %x\n",srcMod->serialnumber,destMod->serialnumber); */ +/* #endif */ + destMod->serialnumber=srcMod->serialnumber; + } + if ((srcMod->nchip)>(destMod->nchip)) { + printf("Number of chip of source is larger than number of chips of destination\n"); + return FAIL; + } + if ((srcMod->nchan)>(destMod->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + if ((srcMod->ndac)>(destMod->ndac)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + if ((srcMod->nadc)>(destMod->nadc)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + +#ifdef VERBOSE + printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); + printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); + printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); + printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); + +#endif + + + + destMod->ndac=srcMod->ndac; + destMod->nadc=srcMod->nadc; + destMod->nchip=srcMod->nchip; + destMod->nchan=srcMod->nchan; + if (srcMod->reg>=0) + destMod->reg=srcMod->reg; +#ifdef VERBOSE + printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); +#endif + if (srcMod->gain>=0) + destMod->gain=srcMod->gain; + if (srcMod->offset>=0) + destMod->offset=srcMod->offset; + + // printf("copying gain and offset %f %f to %f %f\n",srcMod->gain,srcMod->offset,destMod->gain,destMod->offset); + + for (ichip=0; ichip<(srcMod->nchip); ichip++) { + if (*((srcMod->chipregs)+ichip)>=0) + *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); + } + for (ichan=0; ichan<(srcMod->nchan); ichan++) { + if (*((srcMod->chanregs)+ichan)>=0) + *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); + } + for (idac=0; idac<(srcMod->ndac); idac++) { + if (*((srcMod->dacs)+idac)>=0) + *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } + for (iadc=0; iadc<(srcMod->nadc); iadc++) { + if (*((srcMod->adcs)+iadc)>=0) + *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); + } + return ret; +} + + + +/* Register commands */ + + +int clearDACSregister(int imod) { + + putout("1111111111111111",imod);//reset + putout("1111111111111110",imod);//cs down + + /* commented out by dhanya + putout("0000000001000000",imod); + putout("0000000101000000",imod); + putout("0000000101000000",imod); + putout("0000000001000000",imod); + */ +#ifdef DEBUG + fprintf(stdout, "Clearing DAC shiftregister\n"); +#endif + // sDac=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + +int nextDAC(int imod) { + + putout("1111111111111011",imod);//cs up + putout("1111111111111001",imod);//clk down + putout("1111111111111111",imod);//reset + + /*commented out by dhanya + putout("0000000001000000",imod); + putout("0000000001001000",imod); + putout("0000000001000000",imod); + */ +#ifdef DEBUG + fprintf(stdout, "Next DAC\n"); +#endif + // sDac++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + + +int clearCSregister(int imod) { + + putout("0000000001000000",imod); + putout("0000100001000000",imod); + putout("0000100001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Clearing CS shiftregister\n"); +#endif + /* + sChan=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + */ + sChip=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + //putout("0000000000000000",imod); + return 0; +} + +int setCSregister(int imod){ + + putout("0000000001000000",imod); + putout("0001000001000000",imod); + putout("0001000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Setting CS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChip=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextChip(int imod){ + + putout("0000000001000000",imod); + putout("0010000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Next Chip\n"); +#endif + sChip++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int firstChip(int imod){ + + putout("0100000001000000",imod); + putout("0110000001000000",imod); + putout("0100000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "First Chip\n"); +#endif + sChip=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int clearSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0000111000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Clearing SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int setSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0001011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Setting SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextStrip(int imod){ + putout("0000011000000000",imod); + putout("0010011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"|-"); +#endif + sChan++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int selChannel(const int strip,int imod) { + int istrip; + clearSSregister(imod); + nextStrip(imod); + for (istrip=0; istrip=0 && imod=0) + initDAC(ind,val, imod); + + if (imod>=0 && imodndac) + return (detectorDacs[ind+imod*NDAC]); + } + return FAIL; + */ + return setDACRegister(ind, -1, imod); +} + + +int initDAC(int dac_addr, int value, int imod) { +// int i; +#ifdef VERBOSE + printf("Programming dac %d with value %d\n", dac_addr, value); +#endif + clearDACSregister(imod); + program_one_dac(dac_addr,value,imod); + nextDAC(imod); + clearDACSregister(imod); + + return 0; +} + +int getTemperatureByModule(int tempSensor, int imod) +{ + int im; + //for the particular module + if (imod>=0 && imod=0 && imod=0 && imod=0) { +#ifdef VERBOSE + fprintf(stdout, "voltage %d\n", *(v+iaddr)); +#endif + program_one_dac(iaddr, *(v+iaddr),imod); + } + nextDAC(imod); + } + + + clearDACSregister(imod); + + return 0; + +} + + + + +int setSettings(int i, int imod) { +#ifdef VERBOSE + if(i==-1) + printf("\nReading settings of detector...\n"); + else + printf("\ninside set settings wit settings=%d...\n",i); +#endif + int confgain[] = CONF_GAIN; + int isett=-2,retval; + + //reading settings + if(i==GET_SETTINGS){ + retval=initConfGainByModule(i,i,imod); + if(retval==i) + isett=UNDEFINED; + } + //writing settings + else{ + retval=initConfGainByModule(i,confgain[i],imod); + if(retval!=i) + isett=UNDEFINED; + } + //if error while read/writing + if(isett==UNDEFINED) + printf("Error:Weird Value read back from the Gain/Settings Reg\n"); + else{ + //validating the settings read back + if((retval>=HIGHGAIN)&&(retval<=VERYHIGHGAIN)) + isett=retval; + else{ + isett=UNDEFINED; + printf("Error:Wrong Settings Read out:%d\n",retval); + } + } + thisSettings=isett; +#ifdef VERBOSE + printf("detector settings are %d\n",thisSettings); +#endif + return thisSettings; +} + + + + +/* Initialization*/ + +int initChannelbyNumber(sls_detector_channel myChan) { + int reg=myChan.reg; + int ft=reg & TRIM_DR; + int cae=(reg>>(NTRIMBITS))&1; + int ae=(reg>>(NTRIMBITS+1))&1; + int coe=(reg>>(NTRIMBITS+2))&1; + int ocoe=(reg>>(NTRIMBITS+3))&1; + int counts=(reg>>(NTRIMBITS+4)); +#ifdef VERBOSE + printf("Initializing channel %d chip %d module %d reg %x\n",myChan.chan,myChan.chip,myChan.module, reg); + printf("trim %d, cae %d, ae %d, coe %d, ocoe %d, counts %d\n",ft, cae, ae, coe, ocoe, counts); +#endif + + if (myChan.chip<0) + setCSregister(myChan.module); + else + selChip(myChan.chip,myChan.module); + + if (myChan.chan<0) + setSSregister(myChan.module); + else + selChannel(myChan.chan,myChan.module); + + initChannel(ft,cae,ae, coe, ocoe, counts,myChan.module); + + setDynamicRange(dynamicRange); + + setCSregister(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + + return myChan.reg; + +} + +int getChannelbyNumber(sls_detector_channel* myChan) { + int imod, ichip, ichan; + imod=myChan->module; + ichip=myChan->chip; + ichan=myChan->chan; + + if (detectorChans) { + if (imod=0) { + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + myChan->reg=detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan]; + return OK; + } + } + return FAIL; + +} + +int getTrimbit(int imod, int ichip, int ichan) { + if (detectorChans) { + if (imod=0) + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + return (detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan] & TRIM_DR); + } + + return -1; +} + +int initChannel(int ft,int cae, int ae, int coe, int ocoe, int counts, int imod){ + + int ibit, bit, i, im, ichip, ichan; + int chanmi, chanma, chipmi, chipma, modmi, modma; + + + + sMod=imod; + // printf("initializing module %d\n",sMod); + if (imod==ALLMOD) { + sMod=allSelected; + + // printf("initializing all modules\n"); + } + + if (sChan==allSelected) { + // printf("initializing all channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=NCHAN; + } else if (sChan==noneSelected || sChan>NCHAN || sChan<0) { + // printf("initializing no channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=-1; + } else { + // printf("initializing channel %d ft=%d coe=%d\n",sChan, ft,coe); + chanmi=sChan; + chanma=sChan+1; + } + + if (sChip==allSelected) { + // printf("initializing all chips\n"); + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + // printf("initializing no chips\n"); + chipmi=0; + chipma=-1; + } else { + // printf("initializing chip %d\n",sChip); + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + return 1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChans) { + for (im=modmi; im63 || ft<0) { + fprintf(stdout,"Fine Threshold is %d while should be between 0 and 63!",ft); + return 1; + } + /*cal_enable*/ + if (cae) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + } + /*n_an_enable*/ + if (ae) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } else { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } + /*trb5*/ + ibit=5; + bit=ft & (1<>1; + int nchan, ichan; + int ft, cae, ae, coe, ocoe, counts, chanreg; + + + + nchan=myChip.nchan; + if (ichip<0) + setCSregister(imod); + else + selChip(ichip,imod); + + clearSSregister(imod); + for (ichan=0; ichan>(NTRIMBITS+1))&1; + ae=(chanreg>>(NTRIMBITS+2))&1; + coe=((chanreg)>>(NTRIMBITS+3))&1; + ocoe=((chanreg)>>(NTRIMBITS+4))&1; + counts=((chanreg)>>(NTRIMBITS+5)); + nextStrip(imod); + initChannel(ft,cae,ae, coe, ocoe, counts,imod); + } + initChip(obe,ow,imod); + return myChip.reg; + +} + +int getChipbyNumber(sls_detector_chip* myChip){ + int imod, ichip; + imod=myChip->module; + ichip=myChip->chip; + + if (detectorChips) { + if (imodnchip) { + myChip->reg=detectorChips[ichip+imod*NCHIP]; + myChip->nchan=NCHAN; + myChip->chanregs=detectorChans+imod*NCHAN*NCHIP+ichip*NCHIP; + return OK; + } + } + return FAIL; + +} + + + +int initChip(int obe, int ow,int imod){ + int i; + int im, ichip; + int chipmi, chipma, modmi, modma; + /* switch (ow) { + case 0:; + case 1: + setDynamicRange(32); + break; + case 2: + setDynamicRange(16); + break; + case 3: + setDynamicRange(8); + break; + case 4: + setDynamicRange(4); + break; + case 5: + setDynamicRange(1); + break; + default: + setDynamicRange(32); + break; + } + */ + +#ifdef DEBUGOUT + printf("Initializing chip\n"); +#endif + putout("0000000000000000",imod); +#ifdef DEBUGOUT + printf("Output mode= %d\n", ow); +#endif + + /* clearing shift in register */ + for (i=0; i<10; i++) + putout("0000100000000000",imod); + putout("0000000000000000",imod); + + if (ow>0) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + for (i=0; i<(OUTMUX_OFFSET-1); i++) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>1) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>2) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>3) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>4) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + } +#ifdef DEBUGOUT + printf("Output buffer enable= %d\n", obe); +#endif + if (obe) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + /*}*/ + putout("0000000000000000",imod); + + + + + + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + + + if (sChip==allSelected) { + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imNCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imnModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorModules) { + for (im=modmi; imreg)=cm; +#ifdef VERBOSE + printf("imod=%d reg=%d (%x)\n",im,(detectorModules+im)->reg,(unsigned int)((detectorModules+im))); +#endif + } + } + return 0; +} + +int initModulebyNumber(sls_detector_module myMod) { + + printf("\ninside initmoduleynumber..\n"); + + int nchip,nchan;//int ichip, nchip, ichan, nchan; + int im, modmi,modma; + // int ft, cae, ae, coe, ocoe, counts, chanreg; + int imod; + // int obe; + // int ow; + int v[NDAC]; + + + nchip=myMod.nchip; + nchan=(myMod.nchan)/nchip; + + imod=myMod.module; + sMod=imod; + + if (sMod==ALLMOD) + sMod=allSelected; + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {// (sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + + /* + for (idac=0; idacmodule; +#ifdef VERBOSE + printf("Getting module %d\n",imod); +#endif + if (detectorModules) { + copyModule(myMod,detectorModules+imod); + ; + } else + return FAIL; + + return OK; +} + +/* To chips */ +int clearCounter(int imod){ + int i; +#ifdef DEBUG + printf("Clearing counter with contclear\n"); +#endif + putout("0000000000000000",imod); + for (i=0; i<10; i++) + putout("0000000000010000",imod); + putout("0000000000000000",imod); + + return 0; +} + +int clearOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Clearing output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0000110000000000",imod); + putout("0000010000000000",imod); + return 0; +} +int setOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Setting output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0001010000000000",imod); + putout("0000010000000000",imod); + return 0; +} + + +int extPulse(int ncal, int imod) { + int ical; +#ifdef DEBUG + printf("Giving a clock pulse to the counter\n"); +#endif + for (ical=0; ical0 && i%2==0) { + printf("Shift in: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<0 && (dum & (1<0) { + printf("Shift out: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, (dum &1<0 && i%2==0) { + printf("Shift stsel: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<> 1; + + + putout("0000000000000000",ALLMOD); + putout("0010000000000000",ALLMOD); //change mux setting + putout("0000000000000000",ALLMOD); + } + + printf("Test FpgaMux module %d : %d errors\n", imod,result); + if (result) + return 1; + else + return 0; +} + + + + + + + + + +int calibration_sensor(int num, int *v, int *dacs) { + int ich, ichip, imod; + int val[10]; + + + printf("calibrating sensor..."); + for (imod=0; imod=0){ + + if(n==0) + adc=-1; + else{ + //if its for 1 adc or general + if ((arg[0].xmin==0) && (arg[0].xmax==GOTTHARDNCHIP*GOTTHARDNCHAN)) + adc=-1; + else{ + //adc = mid value/numchans also for only 1 roi + adc = ((((arg[0].xmax)+(arg[0].xmin))/2)/(GOTTHARDNCHAN*NCHIPS_PER_ADC)); + if((adc>=0) && (adc<=4)); + else { + printf("warning:adc value greater than 5. deleting roi\n"); + adc=-1; + } + } + } + + + //set rois for just 1 adc - take only 1st roi + if(adc!=-1){ + rois[0].xmin=adc*(GOTTHARDNCHAN*NCHIPS_PER_ADC); + rois[0].xmax=(adc+1)*(GOTTHARDNCHAN*NCHIPS_PER_ADC)-1; + rois[0].ymin=-1; + rois[0].ymax=-1; + nROI = 1; + }else + nROI = 0; + + if((arg[0].xmin!=rois[0].xmin)||(arg[0].xmax!=rois[0].xmax)||(arg[0].ymin!=rois[0].ymin)||(arg[0].ymax!=rois[0].ymax)) + *ret=FAIL; + if(n!=nROI) + *ret=FAIL; + + //set adc of interest + setADC(adc); + }*/ + +//#ifdef VERBOSE + printf("Rois:\n"); + for( i=0;i + + +extern int sockfd; +extern int phase_shift; + + + +void error(char *msg) +{ + perror(msg); +} + +int main(int argc, char *argv[]) +{ + int portno, b; + char cmd[500]; + int retval=OK; + int sd, fd; + int iarg; + + + for(iarg=1; iarg 2) && (!strcasecmp(argv[2],"stopserver"))){ + portno = DEFAULT_PORTNO+1; + if ( sscanf(argv[1],"%d",&portno) ==0) { + printf("could not open stop server: unknown port\n"); + return 1; + } + b=0; + printf("\n\nStop Server\nOpening stop server on port %d\n",portno); + } + + //control server + else { + portno = DEFAULT_PORTNO; + sprintf(cmd,"%s %d stopserver &",argv[0],DEFAULT_PORTNO+1); + printf("\n\nControl Server\nOpening control server on port %d\n",portno ); + + //printf("\n\ncmd:%s\n",cmd); + system(cmd); + b=1; + } + + + init_detector(b); + + + sd=bindSocket(portno); + sockfd=sd; + if (getServerError(sd)) { + printf("server error!\n"); + return -1; + } + + /* assign function table */ + function_table(); +#ifdef VERBOSE + printf("function table assigned \n"); +#endif + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Waiting for client call\n"); +#endif + fd=acceptConnection(sockfd); +#ifdef VERY_VERBOSE + printf("Conenction accepted\n"); +#endif + retval=decode_function(fd); +#ifdef VERY_VERBOSE + printf("function executed\n"); +#endif + closeConnection(fd); +#ifdef VERY_VERBOSE + printf("connection closed\n"); +#endif + } + + exitServer(sockfd); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/moenchDetectorServer/server_defs.h b/slsDetectorSoftware/moenchDetectorServer/server_defs.h new file mode 100755 index 000000000..e86b3107f --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/server_defs.h @@ -0,0 +1,61 @@ +#ifndef SERVER_DEFS_H +#define SERVER_DEFS_H + +#include "sls_detector_defs.h" + +#include + + +// Hardware definitions + +#define NCHAN (160*160) +#define NCHIP 1 +#define NMAXMODX 1 +#define NMAXMODY 1 +#define NMAXMOD (NMAXMODX*NMAXMODY) +#define NDAC 8 +#define NADC 1 + + + + + + +#define NCHANS (NCHAN*NCHIP*NMAXMOD) +#define NDACS (NDAC*NMAXMOD) + +#define NTRIMBITS 6 +#define NCOUNTBITS 24 + +#define NCHIPS_PER_ADC 2 + +//#define TRIM_DR ((2**NTRIMBITS)-1) +//#define COUNT_DR ((2**NCOUNTBITS)-1) +#define TRIM_DR (((int)pow(2,NTRIMBITS))-1) +#define COUNT_DR (((int)pow(2,NCOUNTBITS))-1) + + +#define ALLMOD 0xffff +#define ALLFIFO 0xffff + +#define GOTTHARD_ADCSYNC_VAL 0x32214 +#define ADCSYNC_VAL 0x02111 +#define TOKEN_RESTART_DELAY 0x88000000 +#define TOKEN_RESTART_DELAY_ROI 0x1b000000 +#define TOKEN_TIMING_REV1 0x1f16 +#define TOKEN_TIMING_REV2 0x1f0f + +#define DEFAULT_PHASE_SHIFT 0 // 120 +#define DEFAULT_IP_PACKETSIZE 0x0522 +#define DEFAULT_UDP_PACKETSIZE 0x050E +#define ADC1_IP_PACKETSIZE 256*2+14+20 +#define ADC1_UDP_PACKETSIZE 256*2+4+8+2 + +#ifdef VIRTUAL +#define DEBUGOUT +#endif + +#define CLK_FREQ 65.6E+6 + + +#endif diff --git a/slsDetectorSoftware/moenchDetectorServer/server_funcs.c b/slsDetectorSoftware/moenchDetectorServer/server_funcs.c new file mode 100755 index 000000000..3cd7a7128 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/server_funcs.c @@ -0,0 +1,3088 @@ +#include "sls_detector_defs.h" +#include "server_funcs.h" +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "trimming_funcs.h" +#include "registers_m.h" +#include "gitInfoMoench.h" + +#define FIFO_DATA_REG_OFF 0x50<<11 +#define CONTROL_REG 0x24<<11 +// Global variables + + +int (*flist[256])(int); + + +//defined in the detector specific file +#ifdef MYTHEND +const enum detectorType myDetectorType=MYTHEN; +#elif GOTTHARDD +const enum detectorType myDetectorType=GOTTHARD; +#elif EIGERD +const enum detectorType myDetectorType=EIGER; +#elif PICASSOD +const enum detectorType myDetectorType=PICASSO; +#elif MOENCHD +const enum detectorType myDetectorType=MOENCH; +#else +const enum detectorType myDetectorType=GENERIC; +#endif + + +extern int nModX; +extern int nModY; +extern int dataBytes; +extern int dynamicRange; +extern int storeInRAM; + +extern int lockStatus; +extern char lastClientIP[INET_ADDRSTRLEN]; +extern char thisClientIP[INET_ADDRSTRLEN]; +extern int differentClients; + +/* global variables for optimized readout */ +extern unsigned int *ram_values; +char *dataretval=NULL; +int nframes, iframes, dataret; +char mess[MAX_STR_LENGTH]; + +int digitalTestBit = 0; + + +int init_detector(int b) { + if (mapCSP0()==FAIL) { printf("Could not map memory\n"); + exit(1); + } + + // + + bus_w16(CONTROL_REG, SYNC_RESET); + bus_w16(CONTROL_REG, 0x0); + + //confirm if it is really moench + if(((bus_r(PCB_REV_REG) & DETECTOR_TYPE_MASK)>>DETECTOR_TYPE_OFFSET) != MOENCH_MODULE ){ + printf("This is a Gotthard detector. Exiting Moench Server.\n\n"); + exit(-1); + } + + if (b) { + printf("***This is a MOENCH detector with %d chips per module***\n",NCHIP); + +#ifdef MCB_FUNCS + printf("\nBoard Revision:0x%x\n",(bus_r(PCB_REV_REG)&BOARD_REVISION_MASK)); + initDetector(); + printf("Initializing Detector\n"); + bus_w16(CONTROL_REG, SYNC_RESET); // reset registers +#endif + + + testFpga(); + testRAM(); + printf("ADC_SYNC_REG:%x\n",bus_r(ADC_SYNC_REG)); + //moench specific + + // setPhaseShiftOnce(); //firmware.h + + + prepareADC(); // server_funcs + setADC(-1); //already does setdaqreg and clean fifo + setSettings(GET_SETTINGS,-1); + + //Initialization + setFrames(1); + setTrains(1); + setExposureTime(1e3); + setPeriod(1E6); + setDelay(0); + setGates(0); + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + setMaster(GET_MASTER); + setSynchronization(GET_SYNCHRONIZATION_MODE); + startReceiver(0); //firmware + } + strcpy(mess,"dummy message"); + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + lockStatus=0; + return OK; +} + + +int decode_function(int file_des) { + int fnum,n; + int retval=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveDataOnly(file_des,&fnum,sizeof(fnum)); + if (n <= 0) { +#ifdef VERBOSE + printf("ERROR reading from socket %d, %d %d\n", n, fnum, file_des); +#endif + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif + +#ifdef VERBOSE + printf( "calling function fnum = %d %x\n",fnum,(unsigned int)(flist[fnum])); +#endif + if (fnum<0 || fnum>255) + fnum=255; + retval=(*flist[fnum])(file_des); + if (retval==FAIL) + printf( "Error executing the function = %d \n",fnum); + return retval; +} + + +int function_table() { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_EXEC_COMMAND]=&exec_command; + flist[F_GET_DETECTOR_TYPE]=&get_detector_type; + flist[F_SET_NUMBER_OF_MODULES]=&set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES]=&get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG]=&set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE]=&set_external_communication_mode; + flist[F_GET_ID]=&get_id; + flist[F_DIGITAL_TEST]=&digital_test; + flist[F_WRITE_REGISTER]=&write_register; + flist[F_READ_REGISTER]=&read_register; + flist[F_SET_DAC]=&set_dac; + flist[F_GET_ADC]=&get_adc; + flist[F_SET_CHANNEL]=&set_channel; + flist[F_SET_CHIP]=&set_chip; + flist[F_SET_MODULE]=&set_module; + flist[F_GET_CHANNEL]=&get_channel; + flist[F_GET_CHIP]=&get_chip; + flist[F_GET_MODULE]=&get_module; + flist[F_GET_THRESHOLD_ENERGY]=&get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY]=&set_threshold_energy; + flist[F_SET_SETTINGS]=&set_settings; + flist[F_START_ACQUISITION]=&start_acquisition; + flist[F_STOP_ACQUISITION]=&stop_acquisition; + flist[F_START_READOUT]=&start_readout; + flist[F_GET_RUN_STATUS]=&get_run_status; + flist[F_READ_FRAME]=&read_frame; + flist[F_READ_ALL]=&read_all; + flist[F_START_AND_READ_ALL]=&start_and_read_all; + flist[F_SET_TIMER]=&set_timer; + flist[F_GET_TIME_LEFT]=&get_time_left; + flist[F_SET_DYNAMIC_RANGE]=&set_dynamic_range; + flist[F_SET_ROI]=&set_roi; + flist[F_SET_SPEED]=&set_speed; + flist[F_SET_READOUT_FLAGS]=&set_readout_flags; + flist[F_EXECUTE_TRIMMING]=&execute_trimming; + flist[F_LOCK_SERVER]=&lock_server; + flist[F_SET_PORT]=&set_port; + flist[F_GET_LAST_CLIENT_IP]=&get_last_client_ip; + flist[F_UPDATE_CLIENT]=&update_client; + flist[F_CONFIGURE_MAC]=&configure_mac; + flist[F_LOAD_IMAGE]=&load_image; + flist[F_SET_MASTER]=&set_master; + flist[F_SET_SYNCHRONIZATION_MODE]=&set_synchronization; + flist[F_READ_COUNTER_BLOCK]=&read_counter_block; + flist[F_RESET_COUNTER_BLOCK]=&reset_counter_block; + flist[F_START_RECEIVER]=&start_receiver; + flist[F_STOP_RECEIVER]=&stop_receiver; + flist[F_CALIBRATE_PEDESTAL]=&calibrate_pedestal; + return OK; +} + + +int M_nofunc(int file_des){ + + int ret=FAIL; + sprintf(mess,"Unrecognized Function\n"); + printf(mess); + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + + +int exit_server(int file_des) { + int retval=FAIL; + sendDataOnly(file_des,&retval,sizeof(retval)); + printf("closing server."); + sprintf(mess,"closing server"); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + +int exec_command(int file_des) { + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int retval=OK; + int sysret=0; + int n=0; + + /* receive arguments */ + n = receiveDataOnly(file_des,cmd,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + if (lockStatus==0 || differentClients==0) + sysret=system(cmd); + + //should be replaced by popen + if (sysret==0) { + sprintf(answer,"Succeeded\n"); + if (lockStatus==1 && differentClients==1) + sprintf(answer,"Detector locked by %s\n", lastClientIP); + } else { + sprintf(answer,"Failed\n"); + retval=FAIL; + } + } else { + sprintf(answer,"Could not receive the command\n"); + } + + /* send answer */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + n = sendDataOnly(file_des,answer,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + + /*return ok/fail*/ + return retval; + +} + + + +int get_detector_type(int file_des) { + int n=0; + enum detectorType ret; + int retval=OK; + + sprintf(mess,"Can't return detector type\n"); + + + /* receive arguments */ + /* execute action */ + ret=myDetectorType; + +#ifdef VERBOSE + printf("Returning detector type %d\n",ret); +#endif + + /* send answer */ + /* send OK/failed */ + if (differentClients==1) + retval=FORCE_UPDATE; + + n += sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + + +} + + +int set_number_of_modules(int file_des) { + int n; + int arg[2], ret=0; + int retval=OK; + int dim, nm; + + sprintf(mess,"Can't set number of modules\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket %d", n); + retval=GOODBYE; + } + if (retval==OK) { + dim=arg[0]; + nm=arg[1]; + + /* execute action */ +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + + //if (nm!=GET_FLAG) { + if (dim!=X && nm!=GET_FLAG) { + retval=FAIL; + sprintf(mess,"Can't change module number in dimension %d\n",dim); + } else { + if (lockStatus==1 && differentClients==1 && nm!=GET_FLAG) { + sprintf(mess,"Detector locked by %s\n", lastClientIP); + retval=FAIL; + } else { + ret=setNMod(nm); + if (nModX==nm || nm==GET_FLAG) { + retval=OK; + if (differentClients==1) + retval=FORCE_UPDATE; + } else + retval=FAIL; + } + } + } + /*} else { + if (dim==Y) { + ret=nModY; + } else if (dim==X) { + ret=setNMod(-1); + } + } + */ + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + +} + + +int get_max_number_of_modules(int file_des) { + int n; + int ret; + int retval=OK; + enum dimension arg; + + sprintf(mess,"Can't get max number of modules\n"); + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* execute action */ +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif + + + switch (arg) { + case X: + ret=getNModBoard(); + break; + case Y: + ret=NMAXMODY; + break; + default: + ret=FAIL; + retval=FAIL; + break; + } +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,ret ); +#endif + + + + if (differentClients==1 && retval==OK) { + retval=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + + /*return ok/fail*/ + return retval; +} + + +//index 0 is in gate +//index 1 is in trigger +//index 2 is out gate +//index 3 is out trigger + +int set_external_signal_flag(int file_des) { + int n; + int arg[2]; + int ret=OK; + int signalindex; + enum externalSignalFlag flag, retval; + + sprintf(mess,"Can't set external signal flag\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + retval=SIGNAL_OFF; + if (ret==OK) { + signalindex=arg[0]; + flag=arg[1]; + /* execute action */ + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + + default: + if (differentClients==0 || lockStatus==0) { + retval=setExtSignal(signalindex,flag); + } else { + if (lockStatus!=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n", lastClientIP); + } + } + + } + +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag ); + printf("Set to flag %d\n",retval); +#endif + + } else { + ret=FAIL; + } + + if (ret==OK && differentClients!=0) + ret=FORCE_UPDATE; + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + +int set_external_communication_mode(int file_des) { + int n; + enum externalCommunicationMode arg, ret=GET_EXTERNAL_COMMUNICATION_MODE; + int retval=OK; + + sprintf(mess,"Can't set external communication mode\n"); + + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* + enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE + }; + */ + if (retval==OK) { + /* execute action */ + + ret=setTiming(arg); + + /* switch(arg) { */ + /* default: */ + /* sprintf(mess,"The meaning of single signals should be set\n"); */ + /* retval=FAIL; */ + /* } */ + + +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif + } else + ret=FAIL; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return retval; +} + + + +int get_id(int file_des) { + // sends back 64 bits! + int64_t retval=-1; + int ret=OK; + int n=0; + enum idMode arg; + + sprintf(mess,"Can't return id\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + + switch (arg) { + case DETECTOR_SERIAL_NUMBER: + retval=getDetectorNumber(); + break; + case DETECTOR_FIRMWARE_VERSION: + retval=getFirmwareSVNVersion(); + retval=(retval <<32) | getFirmwareVersion(); + break; + case DETECTOR_SOFTWARE_VERSION: + retval= SVNREV; + retval= (retval <<32) | SVNDATE; + break; +/* case DETECTOR_FIRMWARE_SVN_VERSION: + retval=getFirmwareSVNVersion(); + break;*/ + default: + printf("Required unknown id %d \n", arg); + ret=FAIL; + retval=FAIL; + break; + } + +#ifdef VERBOSE + printf("Id is %llx\n", retval); +#endif + + if (differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int digital_test(int file_des) { + + int retval; + int ret=OK; + int imod=-1; + int n=0; + int ibit=0; + int ow; + int ival; + enum digitalTestMode arg; + + sprintf(mess,"Can't send digital test\n"); + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Digital test mode %d\n",arg ); +#endif + + switch (arg) { + case CHIP_TEST: + n = receiveDataOnly(file_des,&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + retval=0; +#ifdef MCB_FUNCS + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + break; + } + if (imod >= nModX) { + ret=FAIL; + sprintf(mess,"Module %d disabled\n",imod); + break; + } + if (testShiftIn(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftOut(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftStSel(imod)) retval|=(1<<(ibit)); + ibit++; + //if ( testDataInOut(0x123456, imod)) retval|=(1<<(ibit++)); + //if ( testExtPulse(imod)) retval|=(1<<(ibit++)); + // for (ow=0; ow<6; ow++) + // ow=1; + //#ifndef PICASSOD + for (ow=0; ow<5; ow++) { + //#endif + if (testDataInOutMux(imod, ow, 0x789abc)) retval|=(1<=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + +#ifdef MCB_FUNCS + switch (ind) { + case V_DAC0 : + idac=VDAC0; + break; + case V_DAC1: + idac=VDAC1; + break; + case V_DAC2: + idac=VDAC2; + break; + case V_DAC3: + idac=VDAC3; + break; + case V_DAC4: + idac=VDAC4; + break; + case V_DAC5: + idac=VDAC5; + break; + case V_DAC6: + idac=VDAC6; + break; + case V_DAC7: + idac=VDAC7; + break; + case HV_POT: + idac=HIGH_VOLTAGE; + break; + + default: + printf("Unknown DAC index %d for Moench\n",ind); + sprintf(mess,"Unknown DAC index %d for Moench\n",ind); + ret=FAIL; + break; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + if(idac==HIGH_VOLTAGE){ + retval[0]=initHighVoltageByModule(val,imod); + ret=FAIL; + if(retval[0]==-2) + strcpy(mess,"Invalid Voltage.Valid values are 0,90,110,120,150,180,200"); + else if(retval[0]==-3) + strcpy(mess,"Weird value read back or it has not been set yet\n"); + else + ret=OK; + }else{ + initDACbyIndexDACU(idac,val,imod,mV,retval); + ret=FAIL; + if(mV) + temp = retval[1]; + else + temp = retval[0]; + if ((abs(temp-val)<=3) || val==-1) { + ret=OK; +#ifdef VERBOSE + printf("DAC set to %d in dac units and %d mV\n", retval[0],retval[1]); +#endif + } + } + } + } + +#endif + + + if(ret==FAIL) + printf("Setting dac %d of module %d: wrote %d but read %d\n", ind, imod, val, temp); + else{ + if (differentClients) + ret=FORCE_UPDATE; + } + + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + +int get_adc(int file_des) { + //default: mod 0 + int retval; + int ret=OK; + int arg[2]; + enum dacIndex ind; + int imod; + int n; + int idac=0; + + sprintf(mess,"Can't read ADC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ind=arg[0]; + imod=arg[1]; + +#ifdef VERBOSE + printf("Getting ADC %d of module %d\n", ind, imod); +#endif + + if (imod>=getNModBoard() || imod<0) + ret=FAIL; + +#ifdef MCB_FUNCS + switch (ind) { + case TEMPERATURE_FPGA: + idac=TEMP_FPGA; + break; + case TEMPERATURE_ADC: + idac=TEMP_ADC; + break; + default: + printf("Unknown DAC index %d\n",ind); + sprintf(mess,"Unknown DAC index %d\n",ind); + ret=FAIL; + break; + } + + if (ret==OK) + retval=getTemperatureByModule(idac,imod); +#endif + +#ifdef VERBOSE + printf("ADC is %d V\n", retval); +#endif + if (ret==FAIL) { + printf("Getting adc %d of module %d failed\n", ind, imod); + } + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int set_channel(int file_des) { + int ret=OK; + sls_detector_channel myChan; + int retval; + int n; + + + sprintf(mess,"Can't set channel\n"); + +#ifdef VERBOSE + printf("Setting channel\n"); +#endif + ret=receiveChannel(file_des, &myChan); + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif + + if (ret==OK) { + if (myChan.module>=getNModBoard()) + ret=FAIL; + if (myChan.chip>=NCHIP) + ret=FAIL; + if (myChan.chan>=NCHAN) + ret=FAIL; + if (myChan.module<0) + myChan.module=ALLMOD; + } + + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChannelbyNumber(myChan); +#endif + } + } + /* Maybe this is done inside the initialization funcs */ + //copyChannel(detectorChans[myChan.module][myChan.chip]+(myChan.chan), &myChan); + + + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + + +int get_channel(int file_des) { + + int ret=OK; + sls_detector_channel retval; + + int arg[3]; + int ichan, ichip, imod; + int n; + + sprintf(mess,"Can't get channel\n"); + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichan=arg[0]; + ichip=arg[1]; + imod=arg[2]; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0 && ichan=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + + if (ret==OK) { + if (myChip.module>=getNModBoard()) + ret=FAIL; + if (myChip.module<0) + myChip.module=ALLMOD; + if (myChip.chip>=NCHIP) + ret=FAIL; + } + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChipbyNumber(myChip); +#endif + } + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + return ret; +} + +int get_chip(int file_des) { + + + int ret=OK; + sls_detector_chip retval; + int arg[2]; + int ichip, imod; + int n; + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichip=arg[0]; + imod=arg[1]; + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0) + ret=OK; + else + ret=FAIL; + + +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#endif + + if (ret==OK) { + if (myModule.module>=getNModBoard()) { + ret=FAIL; + printf("Module number is too large %d\n",myModule.module); + } + if (myModule.module<0) + myModule.module=ALLMOD; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initModulebyNumber(myModule); +#endif + } + } + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + free(myChip); + free(myChan); + free(myDac); + free(myAdc); + + // setDynamicRange(dr); always 16 commented out + + + return ret; +} + + + + +int get_module(int file_des) { + + + int ret=OK; + + + int arg; + int imod; + int n; + + + + sls_detector_module myModule; + int *myChip=malloc(NCHIP*sizeof(int)); + int *myChan=malloc(NCHIP*NCHAN*sizeof(int)); + int *myDac=malloc(NDAC*sizeof(int));/**dhanya*/ + int *myAdc=malloc(NADC*sizeof(int));/**dhanya*/ + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } + + myModule.ndac=NDAC; + myModule.nchip=NCHIP; + myModule.nchan=NCHAN*NCHIP; + myModule.nadc=NADC; + + + + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + imod=arg; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + } +#ifdef VERYVERBOSE + printf("%d %d %x %s\n",(int)(sizeof(mess)),(int)(strlen(mess)),(unsigned int)( mess),mess); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); +#ifdef VERYVERBOSE + printf("message sent %s\n",mess); +#endif + printf("dataret %d\n",dataret); + return dataret; + } + } else { + nframes=0; + while(fifo_read_event()) { + nframes++; + } + dataretval=(char*)ram_values; + dataret=OK; +#ifdef VERBOSE + printf("sending data of %d frames\n",nframes); +#endif + for (iframes=0; iframes-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",(int)(getFrames()+2)); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + if (differentClients) + dataret=FORCE_UPDATE; + } +#ifdef VERBOSE + printf("Frames left %d\n",(int)(getFrames())); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + printf("dataret %d\n",dataret); + return dataret; + } + printf("dataret %d\n",dataret); + return dataret; +} + + + + + + + + +int read_all(int file_des) { + +while(read_frame(file_des)==OK) { + +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + return OK; + + +} + +int start_and_read_all(int file_des) { + //int dataret=OK; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + if (differentClients==1 && lockStatus==1) { + dataret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return dataret; + + } + + startStateMachine(); + + /* ret=startStateMachine(); + if (ret!=OK) { + sprintf(mess,"could not start state machine\n"); + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + #ifdef VERBOSE + printf("could not start state machine\n"); +#endif +} else {*/ + read_all(file_des); +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + //} + + + return OK; + + +} + +int set_timer(int file_des) { + enum timerIndex ind; + int64_t tns; + int n; + int64_t retval; + int ret=OK; + + + sprintf(mess,"can't set timer\n"); + + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&tns,sizeof(tns)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret!=OK) { + printf(mess); + } + +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif + if (ret==OK) { + + if (differentClients==1 && lockStatus==1 && tns!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch(ind) { + case FRAME_NUMBER: + retval=setFrames(tns); + break; + case ACQUISITION_TIME: + retval=setExposureTime(tns); + break; + case FRAME_PERIOD: + retval=setPeriod(tns); + break; + case DELAY_AFTER_TRIGGER: + retval=setDelay(tns); + break; + case GATES_NUMBER: + retval=setGates(tns); + break; + case PROBES_NUMBER: + sprintf(mess,"can't set timer for moench\n"); + ret=FAIL; + break; + case CYCLES_NUMBER: + retval=setTrains(tns); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + } + if (ret!=OK) { + printf(mess); + if (differentClients) + ret=FORCE_UPDATE; + } + + if (ret!=OK) { + printf(mess); + printf("set timer failed\n"); + } else if (ind==FRAME_NUMBER) { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess, "could not allocate RAM for %lld frames\n", tns); + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { +#ifdef VERBOSE + printf("returning ok %d\n",(int)(sizeof(retval))); +#endif + + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + + return ret; + +} + + + + + + + + +int get_time_left(int file_des) { + + enum timerIndex ind; + int n; + int64_t retval; + int ret=OK; + + sprintf(mess,"can't get timer\n"); + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + //#ifdef VERBOSE + + printf("getting time left on timer %d \n",ind); + //#endif + + if (ret==OK) { + switch(ind) { + case FRAME_NUMBER: + printf("getting frames \n"); + retval=getFrames(); + break; + case ACQUISITION_TIME: + retval=getExposureTime(); + break; + case FRAME_PERIOD: + retval=getPeriod(); + break; + case DELAY_AFTER_TRIGGER: + retval=getDelay(); + break; + case GATES_NUMBER: + retval=getGates(); + break; + case PROBES_NUMBER: + retval=getProbes(); + break; + case CYCLES_NUMBER: + retval=getTrains(); + break; + case PROGRESS: + retval=getProgress(); + break; + case ACTUAL_TIME: + retval=getActualTime(); + break; + case MEASUREMENT_TIME: + retval=getMeasurementTime(); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } + + + if (ret!=OK) { + printf("get time left failed\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + + //#ifdef VERBOSE + + printf("time left on timer %d is %lld\n",ind, retval); + //#endif + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=OK) { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } +#ifdef VERBOSE + + printf("data sent\n"); +#endif + + return ret; + + +} + +int set_dynamic_range(int file_des) { + + + + int dr; + int n; + int retval; + int ret=OK; + + + sprintf(mess,"can't set dynamic range\n"); + + + n = receiveDataOnly(file_des,&dr,sizeof(dr)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + if (differentClients==1 && lockStatus==1 && dr>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setDynamicRange(dr); + } + + //if (dr>=0 && retval!=dr) ret=FAIL; + if (ret!=OK) { + sprintf(mess,"set dynamic range failed\n"); + } else { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess,"Could not allocate RAM for the dynamic range selected\n"); + else if (differentClients) + ret=FORCE_UPDATE; + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + +int set_roi(int file_des) { + + int i; + int ret=OK; + int nroi=-1; + int n=0; + int retvalsize=0; + ROI arg[MAX_ROIS]; + ROI* retval=0; + + strcpy(mess,"Could not set/get roi\n"); + + + n = receiveDataOnly(file_des,&nroi,sizeof(nroi)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if(nroi!=-1){ + n = receiveDataOnly(file_des,arg,nroi*sizeof(ROI)); + if (n != (nroi*sizeof(ROI))) { + sprintf(mess,"Received wrong number of bytes for ROI\n"); + ret=FAIL; + } +//#ifdef VERBOSE + /* + printf("Setting ROI to:"); + for( i=0;i=0) { + if (differentClients==1 && lockStatus==1 && val>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch (arg) { + case CLOCK_DIVIDER: + retval=setClockDivider(val); + break; + + case PHASE_SHIFT: + retval=phaseStep(val); + break; + + case OVERSAMPLING: + retval=setOversampling(val); + break; + + default: + ret=FAIL; + sprintf(mess,"Unknown speed parameter %d",arg); + } + } + } + + + switch (arg) { + case CLOCK_DIVIDER: + retval=getClockDivider(); + break; + + case PHASE_SHIFT: + retval=phaseStep(-1); + break; + + case OVERSAMPLING: + retval=setOversampling(-1); + break; + + default: + ret=FAIL; + sprintf(mess,"Unknown speed parameter %d",arg); + } + } + + + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + +int set_readout_flags(int file_des) { + + enum readOutFlags arg; + int n; + int ret=FAIL; + + + receiveDataOnly(file_des,&arg,sizeof(arg)); + + sprintf(mess,"can't set readout flags for moench\n"); + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + return ret; +} + + + + + +int execute_trimming(int file_des) { + + int arg[3]; + int ret=FAIL; + enum trimMode mode; + + sprintf(mess,"can't set execute trimming for moench\n"); + + receiveDataOnly(file_des,&mode,sizeof(mode)); + receiveDataOnly(file_des,arg,sizeof(arg)); + + + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + return ret; +} + + +int lock_server(int file_des) { + + + int n; + int ret=OK; + + int lock; + n = receiveDataOnly(file_des,&lock,sizeof(lock)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (lock)\n"); + ret=FAIL; + } + if (lock>=0) { + if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) + lockStatus=lock; + else { + ret=FAIL; + sprintf(mess,"Server already locked by %s\n", lastClientIP); + } + } + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else + n = sendDataOnly(file_des,&lockStatus,sizeof(lockStatus)); + + return ret; + +} + +int set_port(int file_des) { + int n; + int ret=OK; + int sd=-1; + + enum portType p_type; /** data? control? stop? Unused! */ + int p_number; /** new port number */ + + n = receiveDataOnly(file_des,&p_type,sizeof(p_type)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (ptype)\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&p_number,sizeof(p_number)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (pnum)\n"); + ret=FAIL; + } + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + printf("\n"); + ret=FAIL; + } + + printf("set port %d to %d\n",p_type, p_number); + + sd=bindSocket(p_number); + } + if (sd>=0) { + ret=OK; + if (differentClients ) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + printf("Could not bind port %d\n", p_number); + if (sd==-10) { + sprintf(mess,"Port %d already set\n", p_number); + printf("Port %d already set\n", p_number); + + } + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&p_number,sizeof(p_number)); + closeConnection(file_des); + exitServer(sockfd); + sockfd=sd; + + } + + return ret; + +} + +int get_last_client_ip(int file_des) { + int ret=OK; + int n; + if (differentClients ) + ret=FORCE_UPDATE; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + + return ret; + +} + + +int send_update(int file_des) { + + int ret=OK; + enum detectorSettings t; + int n;//int thr, n; + //int it; + int64_t retval, tns=-1; + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + n = sendDataOnly(file_des,&nModX,sizeof(nModX)); + n = sendDataOnly(file_des,&nModY,sizeof(nModY)); + n = sendDataOnly(file_des,&dynamicRange,sizeof(dynamicRange)); + n = sendDataOnly(file_des,&dataBytes,sizeof(dataBytes)); + t=setSettings(GET_SETTINGS,-1); + n = sendDataOnly(file_des,&t,sizeof(t)); +/* thr=getThresholdEnergy(); + n = sendDataOnly(file_des,&thr,sizeof(thr));*/ + retval=setFrames(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setExposureTime(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setPeriod(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setDelay(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setGates(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); +/* retval=setProbes(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t));*/ + retval=setTrains(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + + if (lockStatus==0) { + strcpy(lastClientIP,thisClientIP); + } + + return ret; + + +} +int update_client(int file_des) { + + int ret=OK; + + sendDataOnly(file_des,&ret,sizeof(ret)); + return send_update(file_des); + + + +} + + +int configure_mac(int file_des) { + + int ret=OK; + char arg[6][50]; + int n; + + int imod=0;//should be in future sent from client as -1, arg[2] + int ipad; + long long int imacadd; + long long int idetectormacadd; + int udpport; + int detipad; + int retval=-100; + + sprintf(mess,"Can't configure MAC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + sscanf(arg[0], "%x", &ipad); + sscanf(arg[1], "%llx", &imacadd); + sscanf(arg[2], "%x", &udpport); + sscanf(arg[3], "%llx", &idetectormacadd); + sscanf(arg[4], "%x", &detipad); +//arg[5] is for eiger +#ifdef VERBOSE + int i; + printf("\ndigital_test_bit in server %d\t",digitalTestBit); + printf("\nipadd %x\t",ipad); + printf("destination ip is %d.%d.%d.%d = 0x%x \n",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff,ipad); + printf("macad:%llx\n",imacadd); + for (i=0;i<6;i++) + printf("mac adress %d is 0x%x \n",6-i,(unsigned int)(((imacadd>>(8*i))&0xFF))); + printf("udp port:0x%x\n",udpport); + printf("detector macad:%llx\n",idetectormacadd); + for (i=0;i<6;i++) + printf("detector mac adress %d is 0x%x \n",6-i,(unsigned int)(((idetectormacadd>>(8*i))&0xFF))); + printf("detipad %x\n",detipad); + printf("\n"); +#endif + + + + if (imod>=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + + //#ifdef VERBOSE + printf("Configuring MAC of module %d at port %x\n", imod, udpport); + //#endif +#ifdef MCB_FUNCS + if (ret==OK){ + if(runBusy()){ + ret=stopStateMachine(); + if(ret==FAIL) + strcpy(mess,"could not stop detector acquisition to configure mac"); + } + + if(ret==OK) + configureMAC(ipad,imacadd,idetectormacadd,detipad,digitalTestBit,udpport); + retval=getAdcConfigured(); + } +#endif + if (ret==FAIL) + printf("configuring MAC of mod %d failed\n", imod); + else + printf("Configuremac successful of mod %d and adc %d\n",imod,retval); + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + /*return ok/fail*/ + return ret; + +} + + + +int load_image(int file_des) { + int retval; + int ret=OK; + int n; + enum imageType index; + short int ImageVals[NCHAN*NCHIP]; + + sprintf(mess,"Loading image failed\n"); + + n = receiveDataOnly(file_des,&index,sizeof(index)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,ImageVals,dataBytes); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + switch (index) { + case DARK_IMAGE : +#ifdef VERBOSE + printf("Loading Dark image\n"); +#endif + break; + case GAIN_IMAGE : +#ifdef VERBOSE + printf("Loading Gain image\n"); +#endif + break; + default: + printf("Unknown index %d\n",index); + sprintf(mess,"Unknown index %d\n",index); + ret=FAIL; + break; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + retval=loadImage(index,ImageVals); + if (retval==-1) + ret = FAIL; + } + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + +int set_master(int file_des) { + + enum masterFlags retval=GET_MASTER; + enum masterFlags arg; + int n; + int ret=OK; + // int regret=OK; + + + sprintf(mess,"can't set master flags\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setMaster(arg); + + } + if (retval==GET_MASTER) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int set_synchronization(int file_des) { + + enum synchronizationMode retval=GET_MASTER; + enum synchronizationMode arg; + int n; + int ret=OK; + //int regret=OK; + + + sprintf(mess,"can't set synchronization mode\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + //ret=setStoreInRAM(0); + // initChipWithProbes(0,0,0, ALLMOD); + retval=setSynchronization(arg); + } + if (retval==GET_SYNCHRONIZATION_MODE) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int read_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + //char *retval=NULL; + short int CounterVals[NCHAN*NCHIP]; + + sprintf(mess,"Read counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + ret=readCounterBlock(startACQ,CounterVals); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,CounterVals[i]); +#endif + } + } + + if(ret!=FAIL){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,CounterVals,dataBytes);//1280*2 + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; +} + + + + + +int reset_counter_block(int file_des) { + + int ret=OK; + int n; + int startACQ; + + sprintf(mess,"Reset counter block failed\n"); + + n = receiveDataOnly(file_des,&startACQ,sizeof(startACQ)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=resetCounterBlock(startACQ); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + + /*return ok/fail*/ + return ret; +} + + + + + + +int start_receiver(int file_des) { + int ret=OK; + int n=0; + strcpy(mess,"Could not start receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret = startReceiver(1); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + + +int stop_receiver(int file_des) { + int ret=OK; + int n=0; + + strcpy(mess,"Could not stop receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifdef MCB_FUNCS + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret=startReceiver(0); + +#endif + + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if(ret==FAIL) + n = sendDataOnly(file_des,mess,sizeof(mess)); + /*return ok/fail*/ + return ret; +} + + + + + +int calibrate_pedestal(int file_des){ + + int ret=OK; + int retval=-1; + int n; + int frames; + + sprintf(mess,"Could not calibrate pedestal\n"); + + n = receiveDataOnly(file_des,&frames,sizeof(frames)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=calibratePedestal(frames); + } + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) + n += sendDataOnly(file_des,mess,sizeof(mess)); + else + n += sendDataOnly(file_des,&retval,sizeof(retval)); + + /*return ok/fail*/ + return ret; +} + + diff --git a/slsDetectorSoftware/moenchDetectorServer/server_funcs.h b/slsDetectorSoftware/moenchDetectorServer/server_funcs.h new file mode 100755 index 000000000..890c7452d --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/server_funcs.h @@ -0,0 +1,97 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H + + +#include "sls_detector_defs.h" + + +#include +/* +#include +#include +#include +*/ +#include "communication_funcs.h" + + + + +#define GOODBYE -200 + +int sockfd; + +int function_table(); + +int decode_function(int); +int init_detector(int); + +int M_nofunc(int); +int exit_server(int); + + + + +// General purpose functions +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); + + +int exec_command(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +int write_register(int); +int read_register(int); +int set_dac(int); +int get_adc(int); +int set_channel(int); +int set_chip(int); +int set_module(int); +int get_channel(int); +int get_chip(int); +int get_module(int); + +int get_threshold_energy(int); +int set_threshold_energy(int); +int set_settings(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int read_frame(int); +int read_all(int); +int start_and_read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_roi(int); +int get_roi(int); +int set_speed(int); +void prepareADC(void); +int set_readout_flags(int); +int execute_trimming(int); +int lock_server(int); +int set_port(int); +int get_last_client_ip(int); +int set_master(int); +int set_synchronization(int); + +int update_client(int); +int send_update(int); +int configure_mac(int); + +int load_image(int); +int read_counter_block(int); +int reset_counter_block(int); + +int start_receiver(int); +int stop_receiver(int); + + +int calibrate_pedestal(int); + +int set_roi(int); + +#endif diff --git a/slsDetectorSoftware/moenchDetectorServer/sharedmemory.c b/slsDetectorSoftware/moenchDetectorServer/sharedmemory.c new file mode 100755 index 000000000..4504cfe05 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/sharedmemory.c @@ -0,0 +1,39 @@ +#include "sharedmemory.h" + +struct statusdata *stdata; + +int inism(int clsv) { + +static int scansmid; + + if (clsv==SMSV) { + if ( (scansmid=shmget(SMKEY,1024,IPC_CREAT | 0666 ))==-1 ) { + return -1; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -2; + } + } + + if (clsv==SMCL) { + if ( (scansmid=shmget(SMKEY,0,0) )==-1 ) { + return -3; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -4; + } + } + return 1; +} + +void write_status_sm(char *status) { + strcpy(stdata->status,status); +} + +void write_stop_sm(int v) { + stdata->stop=v; +} + +void write_runnumber_sm(int v) { + stdata->runnumber=v; +} diff --git a/slsDetectorSoftware/moenchDetectorServer/sharedmemory.h b/slsDetectorSoftware/moenchDetectorServer/sharedmemory.h new file mode 100755 index 000000000..bdbddf719 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/sharedmemory.h @@ -0,0 +1,48 @@ +#ifndef SM +#define SM + +#include "sls_detector_defs.h" + +#include +#include +#include +#include +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +/* key for shared memory */ +#define SMKEY 10001 + +#define SMSV 1 +#define SMCL 2 + + +struct statusdata { + int runnumber; + int stop; + char status[20]; +} ; + + +/* for shared memory */ + +int inism(int clsv); +void write_status_sm(char *status); +void write_stop_sm(int v); +void write_runnumber_sm(int v); + +#endif diff --git a/slsDetectorSoftware/moenchDetectorServer/sls_detector_defs.h b/slsDetectorSoftware/moenchDetectorServer/sls_detector_defs.h new file mode 120000 index 000000000..c5062e03f --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/sls_detector_defs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/moenchDetectorServer/sls_detector_funcs.h b/slsDetectorSoftware/moenchDetectorServer/sls_detector_funcs.h new file mode 120000 index 000000000..844b67129 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/sls_detector_funcs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/moenchDetectorServer/sls_receiver_defs.h b/slsDetectorSoftware/moenchDetectorServer/sls_receiver_defs.h new file mode 120000 index 000000000..1de31caf5 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/sls_receiver_defs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/moenchDetectorServer/sls_receiver_funcs.h b/slsDetectorSoftware/moenchDetectorServer/sls_receiver_funcs.h new file mode 120000 index 000000000..c2ea4ded9 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/sls_receiver_funcs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/moenchDetectorServer/stop_server.c b/slsDetectorSoftware/moenchDetectorServer/stop_server.c new file mode 100755 index 000000000..e3c8ff7e1 --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/stop_server.c @@ -0,0 +1,46 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + + +#include "sls_detector_defs.h" + + +#include "communication_funcs.h" +#include "firmware_funcs.h" + + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + + portno = DEFAULT_PORTNO; + + + bindSocket(portno); + if (getServerError()) + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + acceptConnection(); + retval=stopStateMachine(); + closeConnection(); + } + + exitServer(); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/moenchDetectorServer/trimming_funcs.c b/slsDetectorSoftware/moenchDetectorServer/trimming_funcs.c new file mode 100755 index 000000000..9a28b9b4a --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/trimming_funcs.c @@ -0,0 +1,749 @@ +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "trimming_funcs.h" +#include "mcb_funcs.h" +#include "firmware_funcs.h" +#include + + + +extern int nModX; +//extern int *values; + +extern const int nChans; +extern const int nChips; +extern const int nDacs; +extern const int nAdcs; + + +int trim_fixed_settings(int countlim, int par2, int im) +{ + + int retval=OK; +#ifdef VERBOSE + printf("Trimming with fixed settings\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + if (par2<=0) + retval=trim_with_level(countlim, im); + else + retval=trim_with_median(countlim,im); + + + return retval; +} + + +int trim_with_noise(int countlim, int nsigma, int im) +{ + + + int retval=OK, retval1=OK, retval2=OK; +#ifdef VERBOSE + printf("Trimming using noise\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + /* threshold scan */ + +#ifdef VERBOSE + printf("chosing vthresh and vtrim....."); +#endif + retval1=choose_vthresh_and_vtrim(countlim,nsigma, im); + +#ifdef VERBOSE + printf("trimming with noise.....\n"); +#endif + retval2=trim_with_level(countlim, im); + +#ifdef DEBUGOUT + printf("done\n"); +#endif + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + +int trim_with_beam(int countlim, int nsigma, int im) //rpc +{ + + + int retval=OK, retval1=OK, retval2=OK; + + printf("Trimming using beam\n"); + //return OK; +#ifdef VIRTUAL + printf("Trimming using beam\n"); + return OK; +#endif + /* threshold scan */ +#ifdef DEBUGOUT + printf("chosing vthresh and vtrim....."); +#endif + + retval1=choose_vthresh_and_vtrim(countlim,nsigma,im); + retval2=trim_with_median(TRIM_DR, im); + +#ifdef DEBUGOUT + printf("done\n"); +#endif + + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + + +int trim_improve(int maxit, int par2, int im) //rpc +{ + + int retval=OK, retval1=OK, retval2=OK; + + +#ifdef VERBOSE + printf("Improve the trimming\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + + if (par2!=0 && im==ALLMOD) + retval1=choose_vthresh(); + + retval2=trim_with_median(2*maxit+1, im); +#ifdef DEBUGOUT + printf("done\n"); +#endif + if (retval1==OK && retval2==OK) + retval=OK; + else + retval=FAIL; + + return retval; + +} + +int calcthr_from_vcal(int vcal) { + int thrmin; + //thrmin=140+3*vcal/5; + thrmin=180+3*vcal/5; + return thrmin; +} + +int calccal_from_vthr(int vthr) { + int vcal; + vcal=5*(vthr-140)/3; + return vcal; +} + +int choose_vthresh_and_vtrim(int countlim, int nsigma, int im) { + int retval=OK; +#ifdef MCB_FUNCS + int modma, modmi, nm; + int thr, thrstep=5, nthr=31; + + int *fifodata; + + double vthreshmean, vthreshSTDev; + int *thrmi, *thrma; + double c; + double b=BVTRIM; + double a=AVTRIM; + int *trim; + int ich, imod, ichan; + int nvalid=0; + u_int32_t *scan; + int ithr; + sls_detector_channel myChan; + + + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + trim=malloc(sizeof(int)*nChans*nChips*nModX); + thrmi=malloc(sizeof(int)*nModX); + thrma=malloc(sizeof(int)*nModX); + + + for (ich=0; ichcountlim && trim[ich]==-1) { +//commented out by dhanya trim[ich]=getDACbyIndexDACU(VTHRESH,imod); +#ifdef VERBOSE + // printf("yes: %d %d %d\n",ich,ithr,scan[ich]); +#endif + } +#ifdef VERBOSE + /* else { + printf("no: %d %d %d\n",ich,ithr,scan[ich]); + }*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imodthrmi[imod] && trim[ich]0) { + vthreshmean=vthreshmean/nvalid; + //commented out by dhanya vthreshSTDev=sqrt((vthreshSTDev/nvalid)-vthreshmean*vthreshmean); + } else { + vthreshmean=thrmi[imod]; + vthreshSTDev=nthr*thrstep; + printf("No valid channel for module %d\n",imod); + retval=FAIL; + } + +#ifdef DEBUGOUT + printf("module= %d nvalid = %d mean=%f RMS=%f\n",imod, nvalid, vthreshmean,vthreshSTDev); +#endif + // *vthresh=round(vthreshmean-nsigma*vthreshSTDev); + thr=(int)(vthreshmean-nsigma*vthreshSTDev); + if (thr<0 || thr>(DAC_DR-1)) { + thr=thrmi[imod]/2; + printf("Can't find correct threshold for module %d\n",imod); + retval=FAIL; + } +//commented out by dhanya initDACbyIndexDACU(VTHRESH,thr,imod); +#ifdef VERBOSE + printf("vthresh=%d \n",thr); +#endif + c=CVTRIM-2.*nsigma*vthreshSTDev/63.; + //commented out by dhanya thr=(int)((-b-sqrt(b*b-4*a*c))/(2*a)); + if (thr<500 || thr>(DAC_DR-1)) { + thr=750; + printf("Can't find correct trimbit size for module %d\n",imod); + retval=FAIL; + } + + //commented out by dhanya initDACbyIndexDACU(VTRIM,thr,imod); + +#ifdef VERBOSE + printf("vtrim=%d \n",thr); +#endif + + } + free(trim); + free(thrmi); + free(thrma); + +#endif + return retval; +} + + + + + +int trim_with_level(int countlim, int im) { + int ich, itrim, ichan, ichip, imod; + u_int32_t *scan; + int *inttrim; + int modma, modmi, nm; + int retval=OK; + int *fifodata; + sls_detector_channel myChan; + printf("trimming module number %d", im); + + +#ifdef MCB_FUNCS + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + inttrim=malloc(sizeof(int)*nChips*nChans*nModX); + printf("countlim=%d\n",countlim); + for (ich=0; ichcountlim){ + inttrim[ich]=itrim; + if (scan[ich]>2*countlim && itrim>0) { + //if (scan[ich]>2*countlim || itrim==0) { + inttrim[ich]=itrim-1; + } +#ifdef VERBOSE + printf("Channel %d trimbit %d counted %d (%08x) countlim %d\n",ich,itrim,scan[ich],fifodata[ich],countlim); +#endif + } + } +#ifdef VERBOSE + /* else + printf("Channel %d trimbit %d counted %d countlim %d\n",ich,itrim,scan[ich],countlim);*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imod0) + direction[ichan]=1; + else + direction[ichan]=-1; + } + //commented out by dhanya vthresh=getDACbyIndexDACU(VTHRESH,imod); + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + vthresh=vthresh-direction[ichan]; + if (vthresh>(DAC_DR-1)) { + vthresh=(DAC_DR-1); + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + if (vthresh<0) { + vthresh=0; + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + direction[ichan]=-3; + } else { + vthresh=vthresh+direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } +//commented out by dhanya initDACbyIndex(VTHRESH,vthresh, ichan); + } + } + iteration++; + free(scan); + free(scan1); + } +#endif + return retval; +} + + + + + +int trim_with_median(int stop, int im) { + + + int retval=OK; + +#ifdef MCB_FUNCS + int ichan, imod, ichip, ich; + u_int32_t *scan, *scan1; + int *olddiff, *direction; + int med, diff; + int change_flag=1; + int iteration=0; + int me[nModX], me1[nModX]; + int modma, modmi, nm; + int trim; + int *fifodata; + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + olddiff=malloc(4*nModX*nChips*nChans); + direction=malloc(4*nModX*nChips*nChans); + for (imod=modmi; imod0) { + direction[ichan]=1; + } else { + direction[ichan]=-1; + } + } + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + trim=getTrimbit(imod,ichip,ich)+direction[ichan]; + printf("%d old diff %d < new diff %d %d - trimbit %d\n",ichan, olddiff[ichan], diff, direction[ichan], trim); + direction[ichan]=-3; + } else { + trim=getTrimbit(imod,ichip,ich)-direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } + if (trim>TRIM_DR) { + trim=63; + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + retval=FAIL; + } + if (trim<0) { + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + trim=0; + retval=FAIL; + } + initChannel(trim,0,0,1,0,0,imod); + } + } + } + } + iteration++; + free(scan); + free(scan1); + } + free(olddiff); + free(direction); +#endif + return retval; +} diff --git a/slsDetectorSoftware/moenchDetectorServer/trimming_funcs.h b/slsDetectorSoftware/moenchDetectorServer/trimming_funcs.h new file mode 100755 index 000000000..42ecea24a --- /dev/null +++ b/slsDetectorSoftware/moenchDetectorServer/trimming_funcs.h @@ -0,0 +1,20 @@ +#ifndef TRIMMING_FUNCS_H +#define TRIMMING_FUNCS_H + +#include "sls_detector_defs.h" + +int trim_fixed_settings(int countlim, int par2, int imod); +int trim_with_noise(int countlim, int nsigma, int imod); +int trim_with_beam(int countlim, int nsigma, int imod); +int trim_improve(int maxit, int par2, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); +int choose_vthresh_and_vtrim(int countlim, int nsigma, int imod); + +int choose_vthresh(); +int trim_with_level(int countlim, int imod); +int trim_with_median(int stop, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); + +#endif diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp new file mode 100644 index 000000000..112ccf030 --- /dev/null +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.cpp @@ -0,0 +1,5592 @@ +/******************************************************************* + +Date: $Date$ +Revision: $Rev$ +Author: $Author$ +URL: $URL$ +ID: $Id$ + +********************************************************************/ + + + +#include "multiSlsDetector.h" +#include "slsDetector.h" +#include "multiSlsDetectorCommand.h" +#include "multiSlsDetectorClient.h" +#include "postProcessingFuncs.h" +#include "usersFunctions.h" +#include "ThreadPool.h" + +#include +#include +#include +#include +#include +using namespace std; + + +char ans[MAX_STR_LENGTH]; + +int multiSlsDetector::freeSharedMemory() { + // Detach Memory address + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) + detectors[id]->freeSharedMemory(); + } + + + if (shmdt(thisMultiDetector) == -1) { + perror("shmdt failed\n"); + return FAIL; + } + printf("Shared memory %d detached\n", shmId); + // remove shared memory + if (shmctl(shmId, IPC_RMID, 0) == -1) { + perror("shmctl(IPC_RMID) failed\n"); + return FAIL; + } + printf("Shared memory %d deleted\n", shmId); + return OK; + +} + + + +int multiSlsDetector::initSharedMemory(int id=0) { + + key_t mem_key=DEFAULT_SHM_KEY+MAXDET+id; + int shm_id; + int sz; + + + + sz=sizeof(sharedMultiSlsDetector); + + +#ifdef VERBOSE + std::cout<<"multiSlsDetector: Size of shared memory is "<< sz << " - id " << mem_key << std::endl; +#endif + shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory + + if (shm_id < 0) { + std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; + return shm_id; + } + + /** + thisMultiDetector pointer is set to the memory address of the shared memory + */ + + thisMultiDetector = (sharedMultiSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ + + if (thisMultiDetector == (void*)-1) { + std::cout<<"*** shmat error (server) ***" << std::endl; + return shm_id; + } + /** + shm_id returns -1 is shared memory initialization fails + */ + + return shm_id; + +} + + + + +multiSlsDetector::multiSlsDetector(int id) : slsDetectorUtils(), shmId(-1) +{ + + while (shmId<0) { + shmId=initSharedMemory(id); + id++; + } + id--; + + for (int id=0; idalreadyExisting==0) { + + + thisMultiDetector->onlineFlag = ONLINE_FLAG; + thisMultiDetector->numberOfDetectors=0; + for (int id=0; iddetectorIds[id]=-1; + thisMultiDetector->offsetX[id]=0; + thisMultiDetector->offsetY[id]=0; + } + thisMultiDetector->masterPosition=-1; + thisMultiDetector->dataBytes=0; + thisMultiDetector->numberOfChannels=0; + thisMultiDetector->numberOfChannel[X]=0; + thisMultiDetector->numberOfChannel[Y]=0; + + thisMultiDetector->maxNumberOfChannels=0; + thisMultiDetector->maxNumberOfChannel[X]=0; + thisMultiDetector->maxNumberOfChannel[Y]=0; + + thisMultiDetector->maxNumberOfChannelsPerDetector[X]=-1; + thisMultiDetector->maxNumberOfChannelsPerDetector[Y]=-1; + + /** set trimDsdir, calDir and filePath to default to root directory*/ + strcpy(thisMultiDetector->filePath,"/"); + /** set fileName to default to run*/ + strcpy(thisMultiDetector->fileName,"run"); + /** set fileIndex to default to 0*/ + thisMultiDetector->fileIndex=0; + /** set frames per file to default to 1*/ + thisMultiDetector->framesPerFile=1; + + /** set progress Index to default to 0*/ + thisMultiDetector->progressIndex=0; + /** set total number of frames to be acquired to default to 1*/ + thisMultiDetector->totalProgress=1; + + + + + /** set correction mask to 0*/ + thisMultiDetector->correctionMask=1<correctionMask|=(1<tDead=0; + /** sets bad channel list file to none */ + strcpy(thisMultiDetector->badChanFile,"none"); + /** sets flat field correction directory */ + strcpy(thisMultiDetector->flatFieldDir,getenv("HOME")); + /** sets flat field correction file */ + strcpy(thisMultiDetector->flatFieldFile,"none"); + /** set angular direction to 1*/ + thisMultiDetector->angDirection=1; + /** set fine offset to 0*/ + thisMultiDetector->fineOffset=0; + /** set global offset to 0*/ + thisMultiDetector->globalOffset=0; + + + + /** set threshold to -1*/ + thisMultiDetector->currentThresholdEV=-1; + // /** set clockdivider to 1*/ + // thisMultiDetector->clkDiv=1; + /** set number of positions to 0*/ + thisMultiDetector->numberOfPositions=0; + /** sets angular conversion file to none */ + strcpy(thisMultiDetector->angConvFile,"none"); + /** set binsize*/ + thisMultiDetector->binSize=0.001; + thisMultiDetector->stoppedFlag=0; + + thisMultiDetector->threadedProcessing=1; + + thisMultiDetector->actionMask=0; + + + for (int ia=0; iaactionMode[ia]=0; + strcpy(thisMultiDetector->actionScript[ia],"none"); + strcpy(thisMultiDetector->actionParameter[ia],"none"); + } + + + for (int iscan=0; iscanscanMode[iscan]=0; + strcpy(thisMultiDetector->scanScript[iscan],"none"); + strcpy(thisMultiDetector->scanParameter[iscan],"none"); + thisMultiDetector->nScanSteps[iscan]=0; + thisMultiDetector->scanPrecision[iscan]=0; + } + + thisMultiDetector->receiver_read_freq = 0; + thisMultiDetector->acquiringFlag = false; + thisMultiDetector->alreadyExisting=1; + } + + + //assigned before creating detector + stoppedFlag=&thisMultiDetector->stoppedFlag; + threadedProcessing=&thisMultiDetector->threadedProcessing; + actionMask=&thisMultiDetector->actionMask; + actionScript=thisMultiDetector->actionScript; + actionParameter=thisMultiDetector->actionParameter; + nScanSteps=thisMultiDetector->nScanSteps; + scanMode=thisMultiDetector->scanMode; + scanScript=thisMultiDetector->scanScript; + scanParameter=thisMultiDetector->scanParameter; + scanSteps=thisMultiDetector->scanSteps; + scanPrecision=thisMultiDetector->scanPrecision; + numberOfPositions=&thisMultiDetector->numberOfPositions; + detPositions=thisMultiDetector->detPositions; + angConvFile=thisMultiDetector->angConvFile; + correctionMask=&thisMultiDetector->correctionMask; + binSize=&thisMultiDetector->binSize; + fineOffset=&thisMultiDetector->fineOffset; + globalOffset=&thisMultiDetector->globalOffset; + angDirection=&thisMultiDetector->angDirection; + flatFieldDir=thisMultiDetector->flatFieldDir; + flatFieldFile=thisMultiDetector->flatFieldFile; + badChanFile=thisMultiDetector->badChanFile; + timerValue=thisMultiDetector->timerValue; + + expTime=&timerValue[ACQUISITION_TIME]; + + currentSettings=&thisMultiDetector->currentSettings; + currentThresholdEV=&thisMultiDetector->currentThresholdEV; + moveFlag=NULL; + + sampleDisplacement=thisMultiDetector->sampleDisplacement; + + filePath=thisMultiDetector->filePath; + fileName=thisMultiDetector->fileName; + fileIndex=&thisMultiDetector->fileIndex; + framesPerFile=&thisMultiDetector->framesPerFile; + + + for (int i=0; inumberOfDetectors; i++) { +#ifdef VERBOSE + cout << thisMultiDetector->detectorIds[i] << endl; +#endif + detectors[i]=new slsDetector(thisMultiDetector->detectorIds[i], this); + + + // setAngularConversionPointer(detectors[i]->getAngularConversionPointer(),detectors[i]->getNModsPointer(),detectors[i]->getNChans()*detectors[i]->getNChips(), i); + + } + // for (int i=thisMultiDetector->numberOfDetectors; ilastPID=getpid(); + + + getNMods(); + getMaxMods(); + threadpool = 0; + if(createThreadPool() == FAIL) + exit(-1); + +} + +multiSlsDetector::~multiSlsDetector() { + //removeSlsDetector(); + destroyThreadPool(); +} + + +int multiSlsDetector::createThreadPool(){ + if(threadpool){ + threadpool->destroy_threadpool(); + threadpool=0; + } + if(thisMultiDetector->numberOfDetectors < 1){ + cout << "No detectors attached to create threadpool" << endl; + return OK; + } + threadpool = new ThreadPool(thisMultiDetector->numberOfDetectors); + switch(threadpool->initialize_threadpool()){ + case 0: + cerr << "Failed to initialize thread pool!" << endl; + return FAIL; + case 1: +#ifdef VERBOSE + cout << "Not initializing threads, only one detector" << endl; +#endif + break; + default: +#ifdef VERBOSE + cout << "Initialized Threadpool" << endl; +#endif + break; + } + return OK; +} + +void multiSlsDetector::destroyThreadPool(){ + if(threadpool){ + threadpool->destroy_threadpool(); + threadpool=0; +#ifdef VERBOSE + cout<<"Destroyed Threadpool"<numberOfDetectors; + + + if (slsDetector::exists(id)==0) { + cout << "Detector " << id << " does not exist - You should first create it to determine type etc." << endl; + } + +#ifdef VERBOSE + cout << "Adding detector " << id << " in position " << pos << endl; +#endif + + if (pos<0) + pos=j; + + if (pos>j) + pos=thisMultiDetector->numberOfDetectors; + + + + //check that it is not already in the list + + for (int i=0; inumberOfDetectors; i++) { + //check that it is not already in the list, in that case move to new position + if (detectors[i]) { + if (detectors[i]->getDetectorId()==id) { + cout << "Detector " << id << "already part of the multiDetector in position " << i << "!" << endl << "Remove it before adding it back in a new position!"<< endl; + return -1; + } + } + } + + + + if (pos!=thisMultiDetector->numberOfDetectors) { + for (int ip=thisMultiDetector->numberOfDetectors-1; ip>=pos; ip--) { +#ifdef VERBOSE + cout << "Moving detector " << thisMultiDetector->detectorIds[ip] << " from position " << ip << " to " << ip+1 << endl; +#endif + thisMultiDetector->detectorIds[ip+1]=thisMultiDetector->detectorIds[ip]; + detectors[ip+1]=detectors[ip]; + } + } +#ifdef VERBOSE + cout << "Creating new detector " << pos << endl; +#endif + + detectors[pos]=new slsDetector(id, this); + thisMultiDetector->detectorIds[pos]=detectors[pos]->getDetectorId(); + thisMultiDetector->numberOfDetectors++; + + thisMultiDetector->dataBytes+=detectors[pos]->getDataBytes(); + + thisMultiDetector->numberOfChannels+=detectors[pos]->getTotalNumberOfChannels(); + thisMultiDetector->maxNumberOfChannels+=detectors[pos]->getMaxNumberOfChannels(); + + + + getMaxMods(); + getNMods(); + getMaxMod(X); + getNMod(X); + getMaxMod(Y); + getNMod(Y); + +#ifdef VERBOSE + cout << "Detector added " << thisMultiDetector->numberOfDetectors<< endl; + + for (int ip=0; ipnumberOfDetectors; ip++) { + cout << "Detector " << thisMultiDetector->detectorIds[ip] << " position " << ip << " " << detectors[ip]->getHostname() << endl; + } +#endif + + //set offsets + updateOffsets(); + destroyThreadPool(); + if(createThreadPool() == FAIL) + exit(-1); + + + return thisMultiDetector->numberOfDetectors; + +} + + +void multiSlsDetector::updateOffsets(){ + + cout << endl << "Updating Multi-Detector Offsets" << endl; + + int offsetX=0, offsetY=0, numX=0, numY=0, maxX=0, maxY=0; + int maxChanX = thisMultiDetector->maxNumberOfChannelsPerDetector[X]; + int maxChanY = thisMultiDetector->maxNumberOfChannelsPerDetector[Y]; + int prevChanX=0; + int prevChanY=0; + bool firstTime = true; + + thisMultiDetector->numberOfChannel[X] = 0; + thisMultiDetector->numberOfChannel[Y] = 0; + thisMultiDetector->maxNumberOfChannel[X] = 0; + thisMultiDetector->maxNumberOfChannel[Y] = 0; + + + for (int i=0; inumberOfDetectors; i++) { + if (detectors[i]) { + cout<<"offsetX:"<getTotalNumberOfChannels(Y) <<" maxChanY:"< 0) && ((offsetX + detectors[i]->getTotalNumberOfChannels(X)) > maxChanX)) + cout<<"\nDetector[" << i << "] exceeds maximum channels allowed for complete detector set in X dimension!" << endl; + if ((maxChanY > 0) && ((offsetY + detectors[i]->getTotalNumberOfChannels(Y)) > maxChanY)) + cout<<"\nDetector[" << i << "] exceeds maximum channels allowed for complete detector set in Y dimension!" << endl; + prevChanX = detectors[i]->getTotalNumberOfChannels(X); + prevChanY = detectors[i]->getTotalNumberOfChannels(Y); + numX += detectors[i]->getTotalNumberOfChannels(X); + numY += detectors[i]->getTotalNumberOfChannels(Y); + maxX += detectors[i]->getMaxNumberOfChannels(X); + maxY += detectors[i]->getMaxNumberOfChannels(Y); + cout<<"incrementing in both direction"< 0) && ((offsetY + prevChanY + detectors[i]->getTotalNumberOfChannels(Y)) <= maxChanY))){ + offsetY += prevChanY; + prevChanY = detectors[i]->getTotalNumberOfChannels(Y); + numY += detectors[i]->getTotalNumberOfChannels(Y); + maxY += detectors[i]->getMaxNumberOfChannels(Y); + cout<<"incrementing in y direction"< 0) && ((offsetX + prevChanX + detectors[i]->getTotalNumberOfChannels(X)) > maxChanX)) + cout<<"\nDetector[" << i << "] exceeds maximum channels allowed for complete detector set in X dimension!" << endl; + offsetY = 0; + prevChanY = detectors[i]->getTotalNumberOfChannels(Y);; + numY = 0; //assuming symmetry with this statement. whats on 1st column should be on 2nd column + maxY = 0; + offsetX += prevChanX; + prevChanX = detectors[i]->getTotalNumberOfChannels(X); + numX += detectors[i]->getTotalNumberOfChannels(X); + maxX += detectors[i]->getMaxNumberOfChannels(X); + cout<<"incrementing in x direction"<offsetX[i] = offsetX; + thisMultiDetector->offsetY[i] = offsetY; + cout << "Detector[" << i << "] has offsets (" << thisMultiDetector->offsetX[i] << ", " << thisMultiDetector->offsetY[i] << ")" << endl; + + //offsetY has been reset sometimes and offsetX the first time, but remember the highest values + if(numX > thisMultiDetector->numberOfChannel[X]) + thisMultiDetector->numberOfChannel[X] = numX; + if(numY > thisMultiDetector->numberOfChannel[Y]) + thisMultiDetector->numberOfChannel[Y] = numY; + if(maxX > thisMultiDetector->maxNumberOfChannel[X]) + thisMultiDetector->maxNumberOfChannel[X] = maxX; + if(maxY > thisMultiDetector->maxNumberOfChannel[Y]) + thisMultiDetector->maxNumberOfChannel[Y] = maxY; + } + } + + cout << "Number of Channels in X direction:" << thisMultiDetector->numberOfChannel[X] << endl; + cout << "Number of Channels in Y direction:" << thisMultiDetector->numberOfChannel[Y] << endl << endl; +} + +string multiSlsDetector::setHostname(const char* name, int pos){ + + // int id=0; + string s; + if (pos>=0) { + addSlsDetector(name, pos); + if (detectors[pos]) + return detectors[pos]->getHostname(); + } else { + size_t p1=0; + s=string(name); + size_t p2=s.find('+',p1); + char hn[1000]; + if (p2==string::npos) { + strcpy(hn,s.c_str()); + addSlsDetector(hn, pos); + } else { + while (p2!=string::npos) { + strcpy(hn,s.substr(p1,p2-p1).c_str()); + addSlsDetector(hn, pos); + s=s.substr(p2+1); + p2=s.find('+'); + } + } + } +#ifdef VERBOSE + cout << "-----------------------------set online!" << endl; +#endif + setOnline(ONLINE_FLAG); + + return getHostname(pos); +} + +string multiSlsDetector::ssetDetectorsType(string name, int pos) { + + + // int id=0; + string s; + if (pos>=0) { + if (getDetectorType(name)!=GET_DETECTOR_TYPE) + addSlsDetector(name.c_str(), pos); + } else { + removeSlsDetector(); //reset detector list! + size_t p1=0; + s=string(name); + size_t p2=s.find('+',p1); + char hn[1000]; + if (p2==string::npos) { + strcpy(hn,s.c_str()); + addSlsDetector(hn, pos); + } else { + while (p2!=string::npos) { + strcpy(hn,s.substr(p1,p2-p1).c_str()); + if (getDetectorType(hn)!=GET_DETECTOR_TYPE) + addSlsDetector(hn, pos); + s=s.substr(p2+1); + p2=s.find('+'); + } + } + } + return sgetDetectorsType(pos); + +} + +string multiSlsDetector::getHostname(int pos) { + + string s=string(""); +#ifdef VERBOSE + cout << "returning hostname" << pos << endl; +#endif + if (pos>=0) { + if (detectors[pos]) + return detectors[pos]->getHostname(); + } else { + for (int ip=0; ipnumberOfDetectors; ip++) { +#ifdef VERBOSE + cout << "detector " << ip << endl; +#endif + if (detectors[ip]) { + s+=detectors[ip]->getHostname(); + s+=string("+"); + } + cout << s <=0) { + if (detectors[pos]) + return detectors[pos]->getDetectorsType(); + } else if (detectors[0]) + return detectors[0]->getDetectorsType(); + return s; +} + + +string multiSlsDetector::sgetDetectorsType(int pos) { + + string s=string(""); +#ifdef VERBOSE + cout << "returning type" << pos << endl; +#endif + if (pos>=0) { + if (detectors[pos]) + return detectors[pos]->sgetDetectorsType(); + } else { + for (int ip=0; ipnumberOfDetectors; ip++) { +#ifdef VERBOSE + cout << "detector " << ip << endl; +#endif + if (detectors[ip]) { + s+=detectors[ip]->sgetDetectorsType(); + s+=string("+"); + } +#ifdef VERBOSE + cout << "type " << s << endl; +#endif + } + } + return s; + +} + + + + +int multiSlsDetector::getDetectorId(int pos) { + +#ifdef VERBOSE + cout << "Getting detector ID " << pos << endl; +#endif + + if (pos>=0) { + if (detectors[pos]) + return detectors[pos]->getDetectorId(); + } + return -1; +} + + + +int multiSlsDetector::setDetectorId(int ival, int pos){ + + if (pos>=0) { + addSlsDetector(ival, pos); + if (detectors[pos]) + return detectors[pos]->getDetectorId(); + } else { + return -1; + } + return -1; + +} + + +int multiSlsDetector::addSlsDetector(const char *name, int pos) { + + + detectorType t=getDetectorType(string(name)); + int online=0; + slsDetector *s=NULL; + int id; +#ifdef VERBOSE + cout << "Adding detector "<numberOfDetectors; i++) { + if (detectors[i]) { + if (detectors[i]->getHostname()==string(name)) { + cout << "Detector " << name << "already part of the multiDetector in position " << i << "!" << endl<< "Remove it before adding it back in a new position!"<< endl; + return -1; + } + } + } + + //checking that the detector doesn't already exists + + for (id=0; id0) { +#ifdef VERBOSE + cout << "Detector " << id << " already exists" << endl; +#endif + s=new slsDetector(id, this); + if (s->getHostname()==string(name)) + break; + delete s; + s=NULL; + //id++; + } + } + + if (s==NULL) { + t=slsDetector::getDetectorType(name, DEFAULT_PORTNO); + if (t==GENERIC) { + cout << "Detector " << name << "does not exist in shared memory and could not connect to it to determine the type (which is not specified)!" << endl; + setErrorMask(getErrorMask()|MULTI_DETECTORS_NOT_ADDED); + appendNotAddedList(name); + return -1; + } +#ifdef VERBOSE + else + cout << "Detector type is " << t << endl; +#endif + online=1; + } + } +#ifdef VERBOSE + else + cout << "Adding detector by type " << getDetectorType(t) << endl; +#endif + + + + if (s==NULL) { + for (id=0; idsetTCPSocket(name); + setOnline(ONLINE_FLAG); + } + delete s; + } +#ifdef VERBOSE + cout << "Adding it to the multi detector structure" << endl; +#endif + return addSlsDetector(id, pos); + + +} + + +int multiSlsDetector::addSlsDetector(detectorType t, int pos) { + + int id; + + if (t==GENERIC) { + return -1; + } + + for (id=0; id=0 && posnumberOfDetectors) { + if (detectors[pos]) { + ox=thisMultiDetector->offsetX[pos]; + oy=thisMultiDetector->offsetY[pos]; + ret=OK; + } + } + return ret; +} + +int multiSlsDetector::setDetectorOffset(int pos, int ox, int oy) { + + + int ret=FAIL; + + if (pos>=0 && posnumberOfDetectors) { + if (detectors[pos]) { + if (ox!=-1) + thisMultiDetector->offsetX[pos]=ox; + if (oy!=-1) + thisMultiDetector->offsetY[pos]=oy; + ret=OK; + } + } + return ret; +} + + + +int multiSlsDetector::removeSlsDetector(char *name){ + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) { + if (detectors[id]->getHostname()==string(name)) { + removeSlsDetector(id); + } + } + } + return thisMultiDetector->numberOfDetectors; +}; + + + + +int multiSlsDetector::removeSlsDetector(int pos) { + int j; + +#ifdef VERBOSE + cout << "Removing detector in position " << pos << endl; +#endif + + int mi=0, ma=thisMultiDetector->numberOfDetectors, single=0; + + if (pos>=0) { + mi=pos; + ma=pos+1; + single=1; + } + + // if (pos<0 ) + // pos=thisMultiDetector->numberOfDetectors-1; + + if (pos>=thisMultiDetector->numberOfDetectors) + return thisMultiDetector->numberOfDetectors; + + //j=pos; + for (j=mi; jdataBytes-=detectors[j]->getDataBytes(); + thisMultiDetector->numberOfChannels-=detectors[j]->getTotalNumberOfChannels(); + thisMultiDetector->maxNumberOfChannels-=detectors[j]->getMaxNumberOfChannels(); + + delete detectors[j]; + detectors[j]=0; + thisMultiDetector->numberOfDetectors--; + + + if (single) { + for (int i=j+1; inumberOfDetectors+1; i++) { + detectors[i-1]=detectors[i]; + thisMultiDetector->detectorIds[i-1]=thisMultiDetector->detectorIds[i]; + } + detectors[thisMultiDetector->numberOfDetectors]=NULL; + thisMultiDetector->detectorIds[thisMultiDetector->numberOfDetectors]=-1; + } + } + } + + updateOffsets(); + destroyThreadPool(); + if(createThreadPool() == FAIL) + exit(-1); + + return thisMultiDetector->numberOfDetectors; +} + + + + + + + + +int multiSlsDetector::setMaster(int i) { + + int ret=-1, slave=0; + masterFlags f; +#ifdef VERBOSE + cout << "settin master in position " << i << endl; +#endif + if (i>=0 && inumberOfDetectors) { + if (detectors[i]) { +#ifdef VERBOSE + cout << "detector position " << i << " "; +#endif + thisMultiDetector->masterPosition=i; + detectors[i]->setMaster(IS_MASTER); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; id++) { + if (i!=id) { + if (detectors[id]) { +#ifdef VERBOSE + cout << "detector position " << id << " "; +#endif + detectors[id]->setMaster(IS_SLAVE); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; id++) { + if (detectors[id]) { +#ifdef VERBOSE + cout << "detector position " << id << " "; +#endif + detectors[id]->setMaster(NO_MASTER); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; id++) { + if (detectors[id]) { +#ifdef VERBOSE + cout << "detector position " << id << " "; +#endif + f=detectors[id]->setMaster(GET_MASTER); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<0 && ret<0) + ret=-2; + + if (ret<0) + ret=-1; + + thisMultiDetector->masterPosition=ret; + + return thisMultiDetector->masterPosition; +} + +// enum synchronyzationMode { +// GET_SYNCHRONIZATION_MODE=-1, /**< the multidetector will return its synchronization mode */ +// NONE, /**< all detectors are independent (no cabling) */ +// MASTER_GATES, /**< the master gates the other detectors */ +// MASTER_TRIGGERS, /**< the master triggers the other detectors */ +// SLAVE_STARTS_WHEN_MASTER_STOPS /**< the slave acquires when the master finishes, to avoid deadtime */ +// } + +/** + Sets/gets the synchronization mode of the various detectors + \param sync syncronization mode + \returns current syncronization mode +*/ +slsDetectorDefs::synchronizationMode multiSlsDetector::setSynchronization(synchronizationMode sync) { + + + synchronizationMode ret=GET_SYNCHRONIZATION_MODE, ret1=GET_SYNCHRONIZATION_MODE; + + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) { + ret1=detectors[id]->setSynchronization(sync); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<syncMode=ret; + + return thisMultiDetector->syncMode; + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + +int multiSlsDetector::setOnline(int off) { + // int retdet; + + if (off!=GET_ONLINE_FLAG) { + thisMultiDetector->onlineFlag=off; + for (int i=0; inumberOfDetectors; i++) { + if (detectors[i]){ + detectors[i]->setOnline(off); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<onlineFlag; + +}; + + + +string multiSlsDetector::checkOnline() { + string retval1 = "",retval; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + retval=detectors[idet]->checkOnline(); + if(!retval.empty()){ + retval1.append(retval); + retval1.append("+"); + } + } + } + return retval1; +}; + + + +int multiSlsDetector::activate(int const enable){ + int i; + int64_t ret1=-100, ret; + + for (i=0; inumberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->activate(enable); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<alreadyExisting; +} + + + + +// Initialization functions + + + + + +int multiSlsDetector::getThresholdEnergy(int pos) { + + + int i, posmin, posmax; + int ret1=-100, ret; + + if (pos<0) { + posmin=0; + posmax=thisMultiDetector->numberOfDetectors; + } else { + posmin=pos; + posmax=pos+1; + } + + for (i=posmin; igetThresholdEnergy(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<(ret1+200)) + ret1=FAIL; + + } + + } + thisMultiDetector->currentThresholdEV=ret1; + return ret1; + + +} + + +int multiSlsDetector::setThresholdEnergy(int e_eV, int pos, detectorSettings isettings) { + + int i, posmin, posmax; + int ret1=-100, ret; + + if (pos<0) { + posmin=0; + posmax=thisMultiDetector->numberOfDetectors; + } else { + posmin=pos; + posmax=pos+1; + } + + for (i=posmin; isetThresholdEnergy(e_eV,-1,isettings); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<(ret1+200)) + ret1=FAIL; + +#ifdef VERBOSE + cout << "return value " << ret1 << endl; +#endif + } + + } + thisMultiDetector->currentThresholdEV=ret1; + return ret1; + +} + +slsDetectorDefs::detectorSettings multiSlsDetector::getSettings(int pos) { + + int i, posmin, posmax; + int ret=-100; + + if (pos<0) { + posmin=0; + posmax=thisMultiDetector->numberOfDetectors; + } else { + posmin=pos; + posmax=pos+1; + } + + if(!threadpool){ + cout << "Error in creating threadpool. Exiting" << endl; + return GET_SETTINGS; + }else{ + //return storage values + int* iret[posmax-posmin]; + for(int idet=posmin; idet(&slsDetector::getSettings, + detectors[idet],-1,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=posmin; idetgetErrorMask()) + setErrorMask(getErrorMask()|(1<currentSettings=(detectorSettings)ret; + return (detectorSettings)ret; +} + +slsDetectorDefs::detectorSettings multiSlsDetector::setSettings(detectorSettings isettings, int pos) { + + int posmin, posmax; + int ret=-100; + + if (pos<0) { + posmin=0; + posmax=thisMultiDetector->numberOfDetectors; + } else { + posmin=pos; + posmax=pos+1; + } + + if(!threadpool){ + cout << "Error in creating threadpool. Exiting" << endl; + return GET_SETTINGS; + }else{ + //return storage values + int* iret[posmax-posmin]; + for(int idet=posmin; idet(&slsDetector::setSettings, + detectors[idet],isettings,-1,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=posmin; idetgetErrorMask()) + setErrorMask(getErrorMask()|(1<currentSettings=(detectorSettings)ret; + return (detectorSettings)ret; + +} + + + +int multiSlsDetector::getChanRegs(double* retval,bool fromDetector){ + //nChansDet and currentNumChans is because of varying channel size per detector + int n = thisMultiDetector->numberOfChannels,nChansDet,currentNumChans=0; + double retval1[n]; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + // cout << "det " << idet << endl; + nChansDet = detectors[idet]->getChanRegs(retval1,fromDetector); + // cout << "returned" << endl; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (i!=thisMultiDetector->masterPosition) + if (detectors[i]) { + ret=detectors[i]->startAcquisition(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition>=0) { + if (detectors[i]) { + ret=detectors[i]->startAcquisition(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition>=0) { + if (detectors[i]) { + ret=detectors[i]->stopAcquisition(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->stopAcquisition(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition; + if (i>=0) { + if (detectors[i]) { + ret=detectors[i]->startReadOut(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->startReadOut(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<dataBytes/sizeof(int); + int n; + int* retval=new int[nel]; + int *retdet, *p=retval; + int nodata=1, nodatadet=-1;; + + + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) { + retdet=detectors[id]->getDataFromDetector(p); + n=detectors[id]->getDataBytes(); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getDetectorsType() != EIGER) + break; + } + p+=n/sizeof(int); + } + } + + //eiger returns only null + if(getDetectorsType() == EIGER) + return NULL; + + if (nodatadet>=0) { + for (int id=0; idnumberOfDetectors; id++) { + if (id!=nodatadet) { + if (detectors[id]) { +#ifdef VERBOSE + cout << "Stopping detector "<< id << endl; +#endif + detectors[id]->stopAcquisition(); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getDataFromDetector())) { + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getErrorMask()) + setErrorMask(getErrorMask()|(1<dataBytes/sizeof(int); + int n; + int* retval=new int[nel]; + int *retdet, *p=retval; + + /** probably it's always better to have one integer per channel in any case! */ + + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) { + retdet=detectors[id]->readFrame(); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getDataBytes(); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<onlineFlag==ONLINE_FLAG) { + + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) { + detectors[id]->readAllNoWait(); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; id++) { + if (detectors[id]) { + detectors[id]->disconnectControl(); + } + } + + } + +#ifdef VERBOSE + std::cout<< "received "<< i<< " frames" << std::endl; + //#else + // std::cout << std::endl; +#endif + return dataQueueFront(); // check what we return! + +}; + +int* multiSlsDetector::startAndReadAll(){ + + /** Thread for each detector?!?!?! */ +#ifdef VERBOSE + cout << "Start and read all " << endl; +#endif + + + int* retval; + int i=0; + if (thisMultiDetector->onlineFlag==ONLINE_FLAG) { + + startAndReadAllNoWait(); + + while ((retval=getDataFromDetector())){ + i++; +#ifdef VERBOSE + std::cout<< i << std::endl; + //#else + //std::cout << "-" << flush; +#endif + dataQueue.push(retval); + } + + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) { + detectors[id]->disconnectControl(); + } + } + + } + +#ifdef VERBOSE + std::cout<< "MMMM recieved "<< i<< " frames" << std::endl; + //#else + // std::cout << std::endl; +#endif + return dataQueueFront(); // check what we return! + + +}; + + +int multiSlsDetector::startAndReadAllNoWait(){ + + int i=0; + int ret=OK; + int posmin=0, posmax=thisMultiDetector->numberOfDetectors; + + if(!threadpool){ + cout << "Error in creating threadpool. Exiting" << endl; + return FAIL; + }else{ + int* iret[posmax-posmin]; + for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ + iret[idet]= new int(OK); + Task* task = new Task(new func0_t(&slsDetector::startAndReadAllNoWait, + detectors[idet],iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ + if(iret[idet] != NULL){ + if(*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + }else ret = FAIL; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition>=0) { + if (detectors[i]) { + ret1=detectors[i]->startAndReadAllNoWait(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition>=0) + if (detectors[thisMultiDetector->masterPosition]){ + s = detectors[thisMultiDetector->masterPosition]->getRunStatus(); + if(detectors[thisMultiDetector->masterPosition]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition)); + return s; + } + + for (int i=0; inumberOfDetectors; i++) { + s1=detectors[i]->getRunStatus(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->setTimer(index,t); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<timerValue[index]=ret1; + + return ret1; +}; + + +int64_t multiSlsDetector::getTimeLeft(timerIndex index){ + int i; + int64_t ret1=-100, ret; + + + if (thisMultiDetector->masterPosition>=0) + if (detectors[thisMultiDetector->masterPosition]){ + ret1 = detectors[thisMultiDetector->masterPosition]->getTimeLeft(index); + if(detectors[thisMultiDetector->masterPosition]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition)); + return ret1; + } + + for (i=0; inumberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->getTimeLeft(index); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->setSpeed(index,value); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; ip++) { + if (detectors[ip]) + ret+=detectors[ip]->getDataBytes(); + } + return ret; +} + + + + + + +// Flags +int multiSlsDetector::setDynamicRange(int n, int pos){ + + // cout << "multi " << endl; + int imi, ima, i; + int ret, ret1=-100; + + if (pos<0) { + imi=0; + ima=thisMultiDetector->numberOfDetectors; + } else { + imi=pos; + ima=pos+1; + } + + for (i=imi; idataBytes-=detectors[i]->getDataBytes(); + ret=detectors[i]->setDynamicRange(n); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<dataBytes+=detectors[i]->getDataBytes(); + } + } + + //for usability for the user + if (getDetectorsType() == EIGER){ + if(n == 32){ + std::cout << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32" << std::endl; + setSpeed(CLOCK_DIVIDER,2); + } + else if(n == 16){ + std::cout << "Setting Clock to Half Speed for Dynamic Range of 16" << std::endl; + setSpeed(CLOCK_DIVIDER,1); + } + } + + return thisMultiDetector->dataBytes; +}; + + + + +void multiSlsDetector::verifyMinMaxROI(int n, ROI r[]){ + int temp; + for(int i=0;inumberOfDetectors;i++){ + if (detectors[i]) { + //check x offset range + if ((offsetX >= thisMultiDetector->offsetX[i]) && (offsetX < (thisMultiDetector->offsetX[i]+detectors[i]->getMaxNumberOfChannels(X)))){ + if(offsetY==-1){ + channelX = offsetX - thisMultiDetector->offsetX[i]; + return i; + }else{ + //check y offset range + if((offsetY >= thisMultiDetector->offsetY[i]) && (offsetY< (thisMultiDetector->offsetY[i]+detectors[i]->getMaxNumberOfChannels(Y)))){ + channelX = offsetX - thisMultiDetector->offsetX[i]; + channelY = offsetY - thisMultiDetector->offsetY[i]; + return i; + } + } + } + } + } + return -1; +} + + +int multiSlsDetector::setROI(int n,ROI roiLimits[]){ + int ret1=-100,ret; + int i,xmin,xmax,ymin,ymax,channelX,channelY,idet,lastChannelX,lastChannelY,index,offsetX,offsetY; + bool invalidroi=false; + int ndet = thisMultiDetector->numberOfDetectors; + ROI allroi[ndet][n]; + int nroi[ndet]; + for(i=0;igetMaxNumberOfChannels(X))-1; + lastChannelY = (detectors[idet]->getMaxNumberOfChannels(Y))-1; + + offsetX = thisMultiDetector->offsetX[idet]; + offsetY = thisMultiDetector->offsetY[idet]; + //at the end in x dir + if ((offsetX + lastChannelX) >= xmax) + lastChannelX = xmax - offsetX; + //at the end in y dir + if ((offsetY + lastChannelY) >= ymax) + lastChannelY = ymax - offsetY; + +#ifdef VERBOSE + cout<<"lastChannelX:"<numberOfDetectors;i++){ + cout<<"detector "<numberOfDetectors; i++) { + if (detectors[i]){ +#ifdef VERBOSE + cout << "detector " << i << ":" << endl; +#endif + ret = detectors[i]->setROI(nroi[i],allroi[i]); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; + int nroi[ndet]; + int maxroi = ndet*MAX_ROIS; + ROI temproi; + ROI roiLimits[maxroi]; + ROI* retval = new ROI[maxroi]; + ROI* temp=0; + int index=0; + + //get each detector's roi array + for (i=0; inumberOfDetectors; i++){ + if (detectors[i]){ + temp = detectors[i]->getROI(index); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<offsetX[i]; + roiLimits[n].xmax = temp[j].xmax + thisMultiDetector->offsetX[i]; + roiLimits[n].ymin = temp[j].ymin + thisMultiDetector->offsetY[i]; + roiLimits[n].ymax = temp[j].ymin + thisMultiDetector->offsetY[i]; + n++; + } + } + } + } + + + + //empty roi + if (!n) return NULL; + + + +#ifdef VERBOSE + cout<<"ROI :"<numberOfChannels]; + + // int ich=0; + + double *detp=dataout; + int *datap=datain; + + + for (int i=0; inumberOfDetectors; i++) { + if (detectors[i]) { + detectors[i]->decodeData(datap, detp); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getDataBytes()/sizeof(int); + detp+=detectors[i]->getTotalNumberOfChannels(); + +#ifdef VERBOSE + cout << "done " << endl; +#endif + // for (int j=0; jgetTotalNumberOfChannels(); j++) { + // dataout[ich]=detp[j]; + // ich++; + // } + //delete [] detp; + } + } + + return dataout; +} + +//Correction +/* + enum correctionFlags { + DISCARD_BAD_CHANNELS, + AVERAGE_NEIGHBOURS_FOR_BAD_CHANNELS, + FLAT_FIELD_CORRECTION, + RATE_CORRECTION, + ANGULAR_CONVERSION + } +*/ + + +/////////////////////////////////////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////// + + + + + + + + + + + + + + +int multiSlsDetector::setFlatFieldCorrection(string fname){ + double* data = new double[thisMultiDetector->numberOfChannels];// xmed[thisMultiDetector->numberOfChannels]; + double* ffcoefficients = new double[thisMultiDetector->numberOfChannels]; + double*fferrors = new double[thisMultiDetector->numberOfChannels]; + // int nmed=0; + // int idet=0, ichdet=-1; + char ffffname[MAX_STR_LENGTH*2]; + int nch;//nbad=0, + //int badlist[MAX_BADCHANS]; + int im=0; + + if (fname=="default") { + fname=string(thisMultiDetector->flatFieldFile); + } + + + thisMultiDetector->correctionMask&=~(1<correctionMask&=~(1<flatFieldFile,"none"); + for (int i=0; inumberOfDetectors; i++) { + if (detectors[i]){ + detectors[i]->setFlatFieldCorrection(NULL, NULL); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<flatFieldDir,fname.c_str()); + nch=readDataFile(string(ffffname),data); + + if (nch>thisMultiDetector->numberOfChannels) + nch=thisMultiDetector->numberOfChannels; + + if (nch>0) { + + //???? bad ff chans? + int nm=getNMods(); + int chpm[nm]; + int mMask[nm]; + for (int i=0; i=0) { + strcpy(thisMultiDetector->flatFieldFile,fname.c_str()); + + + thisMultiDetector->correctionMask|=(1<correctionMask&(1<numberOfDetectors; i++) { + if (detectors[i]) { + for (int im=0; imgetNMods(); im++) { + mM[imod]=im+off; + imod++; + } + off+=detectors[i]->getMaxMods(); + } + + + } + } + return getNMods(); +} + + + +int multiSlsDetector::setFlatFieldCorrection(double *corr, double *ecorr) { + int ichdet=0; + double *p, *ep; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + if (corr!=NULL) + p=corr+ichdet; + else + p=NULL; + if (ecorr!=NULL) + ep=ecorr+ichdet; + else + ep=NULL; + detectors[idet]->setFlatFieldCorrection(p, ep); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels(); + } + } + return 0; +} + + + + + + + + + +int multiSlsDetector::getFlatFieldCorrection(double *corr, double *ecorr) { + int ichdet=0; + double *p, *ep; + int ff=1, dff; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + if (corr!=NULL) + p=corr+ichdet; + else + p=NULL; + if (ecorr!=NULL) + ep=ecorr+ichdet; + else + ep=NULL; + dff=detectors[idet]->getFlatFieldCorrection(p, ep); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels(); + } + } + return ff; +} + + + + + + + + + + + + + + + +int multiSlsDetector::getNMods(){ + int nm=0; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + nm+=detectors[idet]->getNMods(); + } + } +#ifdef VERBOSE + cout << "total number of modules is " << nm << endl; +#endif + + return nm; +} + + +int multiSlsDetector::getNMod(dimension d){ + int nm=0; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + nm+=detectors[idet]->getNMod(d); + } + } +#ifdef VERBOSE + cout << "total number of modules in dimension " << d << " is " << nm << endl; +#endif + + return nm; +} + + + +int multiSlsDetector::getChansPerMod(int imod){ + int id=-1, im=-1; +#ifdef VERBOSE + cout << "get chans per mod " << imod << endl; +#endif + decodeNMod(imod, id, im); + if (id >=0) { + if (detectors[id]) { + return detectors[id]->getChansPerMod(im); + } + } + return -1; + +} + +int multiSlsDetector::getMoveFlag(int imod){ + int id=-1, im=-1; + decodeNMod(imod, id, im); + if (id>=0) { + if (detectors[id]) { + return detectors[id]->getMoveFlag(im); + } + } + //default!!! + return 1; +} + + + + +angleConversionConstant * multiSlsDetector::getAngularConversionPointer(int imod){ + int id=-1, im=-1; +#ifdef VERBOSE + cout << "get angular conversion pointer " << endl; +#endif + if (decodeNMod(imod, id, im)>=0) { + if (detectors[id]) { + return detectors[id]->getAngularConversionPointer(im); + } + } + return NULL; + +} + + + +int multiSlsDetector::flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout){ + + int ichdet=0; + double *perr=errin;//*pdata, + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { +#ifdef VERBOSE + cout << " detector " << idet << " offset " << ichdet << endl; +#endif + if (errin) + perr+=ichdet; + detectors[idet]->flatFieldCorrect(datain+ichdet, perr, dataout+ichdet, errout+ichdet); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels();//detectors[idet]->getNChans()*detectors[idet]->getNChips()*detectors[idet]->getNMods(); + } + } + return 0; +}; + + + + + + + + +int multiSlsDetector::setRateCorrection(double t){ + +#ifdef VERBOSE + std::cout<< "Setting rate correction with dead time "<< thisMultiDetector->tDead << std::endl; +#endif + + if (getDetectorsType() == EIGER){ + int ret = OK, ret1= OK; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret=detectors[idet]->setRateCorrection(t); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<correctionMask&=~(1<correctionMask&(1<correctionMask|=(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret=detectors[idet]->setRateCorrection(t); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<correctionMask&(1<correctionMask&(1<tDead << std::endl; +#endif + return 1; + } else + t=0; +#ifdef VERBOSE + std::cout<< "Rate correction is disabled " << std::endl; +#endif + return 0; +}; + +double multiSlsDetector::getRateCorrectionTau(){ + + double ret1=-100,ret; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret=detectors[idet]->getRateCorrectionTau(); + if (ret1==-100) + ret1=ret; + else if (ret!=ret1){ + std::cout<< "Rate correction is different for different readouts " << std::endl; + ret1=-1; + } + } + } + + if (getDetectorsType() == EIGER) + return ret1; + + + + //only mythen + if (thisMultiDetector->correctionMask&(1<tDead << std::endl; +#endif + } else { +#ifdef VERBOSE + std::cout<< "Rate correction is disabled " << std::endl; +#endif + ret1=0; + } + return ret1; + +}; + + + +int multiSlsDetector::getRateCorrection(){ + + if (getDetectorsType() == EIGER){ + return getRateCorrectionTau(); + } + + if (thisMultiDetector->correctionMask&(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + if (errin) + perr+=ichdet; + detectors[idet]->rateCorrect(datain+ichdet, perr, dataout+ichdet, errout+ichdet); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels(); + } + } + return 0; +}; + + +int multiSlsDetector::setBadChannelCorrection(string fname){ + + int badlist[MAX_BADCHANS];// badlistdet[MAX_BADCHANS]; + int nbad=0;//, nbaddet=0, choff=0, idet=0; + int ret=0; + + cout << thisMultiDetector->badChanFile << endl; + + if (fname=="default") + fname=string(thisMultiDetector->badChanFile); + + + + + + ret=setBadChannelCorrection(fname, nbad, badlist); + //#ifdef VERBOSE + cout << "multi: file contained " << ret << " badchans" << endl; + //#endif + if (ret==0) { + thisMultiDetector->correctionMask&=~(1<correctionMask|=(1<badChanFile,fname.c_str()); + } + + return setBadChannelCorrection(nbad,badlist,0); + +} + + + +int multiSlsDetector::setBadChannelCorrection(int nbad, int *badlist, int ff) { + + //#define VERBOSE + + int badlistdet[MAX_BADCHANS]; + int nbaddet=0, choff=0, idet=0; + if (nbad<1) + badlistdet[0]=0; + else + badlistdet[0]=badlist[0]; + + if (nbad>0) { + thisMultiDetector->correctionMask|=(1<=detectors[idet]->getMaxNumberOfChannels()) { + //#ifdef VERBOSE + cout << "setting " << nbaddet << " badchans to detector " << idet << endl; + //#endif + detectors[idet]->setBadChannelCorrection(nbaddet,badlistdet,0); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); + nbaddet=0; + idet++; + if (detectors[idet]==NULL) + break; + } + badlistdet[nbaddet]=(badlist[ich]-choff); + nbaddet++; +#ifdef VERBOSE + cout << nbaddet << " " << badlist[ich] << " " << badlistdet[nbaddet-1] << endl; +#endif + } + } + if (nbaddet>0) { + + if (detectors[idet]) { +#ifdef VERBOSE + cout << "setting " << nbaddet << " badchans to detector " << idet << endl; +#endif + detectors[idet]->setBadChannelCorrection(nbaddet,badlistdet,0); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); + nbaddet=0; + idet++; + } + } + nbaddet=0; + for (int i=idet; inumberOfDetectors; i++) { + #ifdef VERBOSE + cout << "setting " << 0 << " badchans to detector " << i << endl; + #endif + if (detectors[i]) { + detectors[i]->setBadChannelCorrection(nbaddet,badlistdet,0); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[idet]) { +#ifdef VERBOSE + cout << "setting " << 0 << " badchans to detector " << idet << endl; +#endif + detectors[idet]->setBadChannelCorrection(nbaddet,badlistdet,0); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<correctionMask&=~(1<correctionMask&(1<correctionMask&(1<numberOfDetectors; idet++) { + if (detectors[idet]) { +#ifdef VERBOSE + cout << " detector " << idet << endl; +#endif + detectors[idet]->readAngularConversion(infile); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + detectors[idet]->writeAngularConversion(outfile); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + detectors[idet]->getAngularConversion(dir1,a1); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getNMods(); + } + } + } + direction=dir; + + if (thisMultiDetector->correctionMask&(1<< ANGULAR_CONVERSION)) { + return 1; + } + return 0; + + +} + + + +dacs_t multiSlsDetector::setDAC(dacs_t val, dacIndex idac, int mV, int imod) { + dacs_t ret, ret1=-100; + + int id=-1, im=-1; + int dmi=0, dma=thisMultiDetector->numberOfDetectors; + + if (decodeNMod(imod, id, im)>=0) { + dmi=id; + dma=dma+1; + } + + for (int idet=dmi; idetsetDAC(val, idac, mV, im); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; + + if (decodeNMod(imod, id, im)>=0) { + dmi=id; + dma=dma+1; + } + + for (int idet=dmi; idetgetADC(idac, im); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; + + if (decodeNMod(imod, id, im)>=0) { + dmi=id; + dma=dma+1; + } + for (int idet=dmi; idetsetChannel(reg, ichan, ichip, im); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + + if (detectors[idet]) { + + detectors[idet]->setAngularConversionParameter(c,v); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfChannels]; + +// double *p=ang; +// int choff=0; + +// for (int idet=0; idetnumberOfDetectors; idet++) { + +// if (detectors[idet]) { +// #ifdef EPICS +// // cout << "convert angle det " << idet << endl; +// if (idet<2) +// #endif +// p=detectors[idet]->convertAngles(pos); +// #ifdef EPICS +// else //////////// GOOD ONLY AT THE BEAMLINE!!!!!!!!!!!!! +// p=detectors[idet]->convertAngles(0); +// #endif +// for (int ich=0; ichgetTotalNumberOfChannels(); ich++) { +// ang[choff+ich]=p[ich]; +// } +// choff+=detectors[idet]->getTotalNumberOfChannels(); +// delete [] p; +// } +// } +// return ang; +// } + + +int multiSlsDetector::getBadChannelCorrection(int *bad) { + //int ichan; + int *bd, nd, ntot=0, choff=0;; + + if (((thisMultiDetector->correctionMask)&(1<< DISCARD_BAD_CHANNELS))==0) + return 0; + //else + // cout << "bad chans corr enabled "<< thisMultiDetector->correctionMask << endl; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + nd=detectors[idet]->getBadChannelCorrection(); + // cout << "det " << idet << " nbad " << nd << endl; + if (nd>0) { + bd = new int[nd]; + nd=detectors[idet]->getBadChannelCorrection(bd); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getTotalNumberOfChannels()) { + if (bad) bad[ntot]=choff+bd[id]; + ntot++; + } + } + choff+=detectors[idet]->getTotalNumberOfChannels(); + delete [] bd; + } else + ntot+=nd; + + } + } + return ntot; + +} + + +int multiSlsDetector::exitServer() { + + int ival=FAIL, iv; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + iv=detectors[idet]->exitServer(); + if (iv==OK) + ival=iv; + } + } + return ival; +} + + +/** returns the detector trimbit/settings directory */ +char* multiSlsDetector::getSettingsDir() { + string s0="", s1="", s; + + + //char ans[1000]; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + s=detectors[idet]->getSettingsDir(); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + detectors[idet]->setSettingsDir(s); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<setSettingsDir(s.substr(p1,p2-p1)); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=thisMultiDetector->numberOfDetectors) + break; + } + + } + return getSettingsDir(); + + +} + + + + +int multiSlsDetector::setTrimEn(int ne, int *ene) { + + int ret=-100, ret1; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setTrimEn(ne,ene); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->getTrimEn(ene); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + s=detectors[idet]->getCalDir(); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + detectors[idet]->setCalDir(s); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<setCalDir(s.substr(p1,p2-p1)); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=thisMultiDetector->numberOfDetectors) + break; + } + + } + return getCalDir(); + +} + +/** + returns the location of the calibration files + \sa sharedSlsDetector +*/ +char* multiSlsDetector::getNetworkParameter(networkParameter p) { + string s0="", s1="",s ; + + //char ans[1000]; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + s=detectors[idet]->getNetworkParameter(p); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; + + if(!threadpool){ + cout << "Error in creating threadpool. Exiting" << endl; + return getNetworkParameter(p); + }else{ + string* sret[thisMultiDetector->numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + sret[idet]=new string("error"); + Task* task = new Task(new func2_t (&slsDetector::setNetworkParameter, + detectors[idet],p,s,sret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + //doing nothing with the return values + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<setNetworkParameter(p,s.substr(p1,p2-p1)); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=thisMultiDetector->numberOfDetectors) + break; + } + + } + return getNetworkParameter(p); + +} + +int multiSlsDetector::setPort(portType t, int p) { + + int ret=-100, ret1; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setPort(t,p); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->lockServer(p); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + s=detectors[idet]->getLastClientIP(); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setReadOutFlags(flag); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<setExternalCommunicationMode(pol); + if(detectors[0]->getErrorMask()) + setErrorMask(getErrorMask()|(1<<0)); + + + for (int idet=1; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setExternalCommunicationMode(pol); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<setExternalSignalFlags(pol,signalindex); + if(detectors[0]->getErrorMask()) + setErrorMask(getErrorMask()|(1<<0)); + + for (int idet=1; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setExternalSignalFlags(pol,signalindex); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + s=detectors[idet]->getSettingsFile(); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->configureMAC(); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfChannels]; + + ifstream infile; + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { +#ifdef VERBOSE + std::cout<< std::endl<< "Loading "; + if(!index) + std::cout<<"Dark"; + else + std::cout<<"Gain"; + std::cout<<" image from file " << fname << std::endl; +#endif + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + if(detectors[idet]->readDataFile(infile,imageVals)>=0){ + ret1=detectors[idet]->sendImageToDetector(index,imageVals); + if (ret==-100) + ret=ret1; + else if (ret!=ret1) + ret=-1; + } + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfChannels]; + ofstream outfile; + outfile.open(fname.c_str(), ios_base::out); + if (outfile.is_open()) { +#ifdef VERBOSE + std::cout<< std::endl<< "Reading Counter to \""<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->getCounterBlock(arg,startACQ); + if(ret1!=OK) + ret=FAIL; + else{ + ret1=detectors[idet]->writeDataFile(outfile,arg); + if(ret1!=OK) + ret=FAIL; + } + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->resetCounterBlock(startACQ); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->setCounterBit(i); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<dataBytes=0; + thisMultiDetector->numberOfChannels=0; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setDynamicRange(p); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<dataBytes+=detectors[idet]->getDataBytes(); + thisMultiDetector->numberOfChannels+=detectors[idet]->getTotalNumberOfChannels(); + if (ret==-100) + ret=ret1; + else if (ret!=ret1) + ret=-1; + } + } + + //for usability for the user + if (getDetectorsType() == EIGER){ + if(p == 32){ + std::cout << "Setting Clock to Quarter Speed to cope with Dynamic Range of 32" << std::endl; + setSpeed(CLOCK_DIVIDER,2); + } + else if(p == 16){ + std::cout << "Setting Clock to Half Speed for Dynamic Range of 16" << std::endl; + setSpeed(CLOCK_DIVIDER,1); + } + } + return ret; + +} + +int multiSlsDetector::getMaxMods() { + + + int ret=0, ret1; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->getMaxMods(); +#ifdef VERBOSE + cout << "detector " << idet << " maxmods " << ret1 << endl; +#endif + ret+=ret1; + } + } +#ifdef VERBOSE + cout << "max mods is " << ret << endl; +#endif + + return ret; + +} + + + + + int multiSlsDetector::getTotalNumberOfChannels(){thisMultiDetector->numberOfChannels=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; id++) thisMultiDetector->numberOfChannels+=detectors[id]->getTotalNumberOfChannels(); return thisMultiDetector->numberOfChannels;}; + + //int multiSlsDetector::getTotalNumberOfChannels(dimension d){thisMultiDetector->numberOfChannel[d]=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; id++) thisMultiDetector->numberOfChannel[d]+=detectors[id]->getTotalNumberOfChannels(d); return thisMultiDetector->numberOfChannel[d];}; + int multiSlsDetector::getTotalNumberOfChannels(dimension d){return thisMultiDetector->numberOfChannel[d];}; + + int multiSlsDetector::getMaxNumberOfChannels(){thisMultiDetector->maxNumberOfChannels=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; id++) thisMultiDetector->maxNumberOfChannels+=detectors[id]->getMaxNumberOfChannels();return thisMultiDetector->maxNumberOfChannels;}; + + // int multiSlsDetector::getMaxNumberOfChannels(dimension d){thisMultiDetector->maxNumberOfChannel[d]=0; for (int id=0; id< thisMultiDetector->numberOfDetectors; id++) thisMultiDetector->maxNumberOfChannel[d]+=detectors[id]->getMaxNumberOfChannels(d);return thisMultiDetector->maxNumberOfChannel[d];}; + int multiSlsDetector::getMaxNumberOfChannels(dimension d){return thisMultiDetector->maxNumberOfChannel[d];}; + + + + + + +int multiSlsDetector::getMaxMod(dimension d){ + + int ret=0, ret1; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->getNMaxMod(d); +#ifdef VERBOSE + cout << "detector " << idet << " maxmods " << ret1 << " in direction " << d << endl; +#endif + ret+=ret1; + } + } +#ifdef VERBOSE + cout << "max mods in direction "<< d << " is " << ret << endl; +#endif + + return ret; + +} + + +int multiSlsDetector::getMaxNumberOfModules(dimension d) { + + int ret=0, ret1; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->getMaxNumberOfModules(d); + ret+=ret1; + } + } + return ret; + +} + +int multiSlsDetector::setNumberOfModules(int p, dimension d) { + + int ret=0;//, ret1; + int nm, mm, nt=p; + + thisMultiDetector->dataBytes=0; + thisMultiDetector->numberOfChannels=0; + + for (int idet=0; idetnumberOfDetectors; idet++) { + + // cout << "detector " << idet << endl; + if (detectors[idet]) { + if (p<0) + nm=p; + else { + mm=detectors[idet]->getMaxNumberOfModules(); + //mm=detectors[idet]->getMaxMods(); + if (nt>mm) { + nm=mm; + nt-=nm; + } else { + nm=nt; + nt-=nm; + } + } + ret+=detectors[idet]->setNumberOfModules(nm); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<dataBytes+=detectors[idet]->getDataBytes(); + thisMultiDetector->numberOfChannels+=detectors[idet]->getTotalNumberOfChannels(); + } + } + + if(p != -1) + updateOffsets(); + return ret; + +} + +int multiSlsDetector::decodeNMod(int i, int &id, int &im) { +#ifdef VERBOSE + cout << " Module " << i << " belongs to detector " << id << endl;; + cout << getMaxMods(); +#endif + + if (i<0 || i>=getMaxMods()) { + id=-1; + im=-1; +#ifdef VERBOSE + cout << " A---------" << id << " position " << im << endl; +#endif + + return -1; + } + int nm; + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + nm=detectors[idet]->getNMods(); + if (nm>i) { + id=idet; + im=i; +#ifdef VERBOSE + cout << " B---------" <=0) { + if (detectors[id]) { + ret = detectors[id]->getId(mode, im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0) { + if (detectors[id]) { + ret = detectors[id]->digitalTest(mode, im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0) { + if (detectors[id]) { + ret = detectors[id]->executeTrimming(mode, par1, par2, im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + iret[idet]= new int(-1); + Task* task = new Task(new func4_t (&slsDetector::executeTrimming, + detectors[idet],mode,par1,par2,imod,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if (ret==-100) + ret=*iret[idet]; + else if (ret!=*iret[idet]) + ret=-1; + delete iret[idet]; + }else ret=-1; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0) { + if (detectors[id]) { + ret = detectors[id]->loadSettingsFile(fname, im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + iret[idet]= new int(OK); + Task* task = new Task(new func2_t (&slsDetector::loadSettingsFile, + detectors[idet],fname,imod,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if(*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + }else ret = FAIL; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0) { + if (detectors[id]) { + ret = detectors[id]->saveSettingsFile(fname, im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret=detectors[idet]->saveSettingsFile(fname, imod); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0) { + if (detectors[id]) { + ret=detectors[id]->setAllTrimbits(val,im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + iret[idet]= new int(-1); + Task* task = new Task(new func2_t (&slsDetector::setAllTrimbits, + detectors[idet],val,imod,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if (ret==-100) + ret=*iret[idet]; + else if (ret!=*iret[idet]) + ret=-1; + delete iret[idet]; + }else ret=-1; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0) { + if (detectors[id]) { + ret = detectors[id]->loadCalibrationFile(fname, im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + iret[idet]= new int(OK); + Task* task = new Task(new func2_t (&slsDetector::loadCalibrationFile, + detectors[idet],fname,imod,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if(*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + }else ret = FAIL; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0) { + if (detectors[id]) { + ret = detectors[id]->saveCalibrationFile(fname, im); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret=detectors[idet]->saveCalibrationFile(fname, imod); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->writeRegister(addr,val); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->writeAdcRegister(addr,val); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + ret=detectors[i]->readRegister(addr); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + std::cout << std::endl << "#Detector " << i << ":" << std::endl; + + ret=detectors[i]->printReceiverConfiguration(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; + + for (int i=0; ifreeSharedMemory(); + } + } + thisMultiDetector->numberOfDetectors=0; + + multiSlsDetectorClient *cmd; + // char ext[100]; + + + + string ans; + string str; + ifstream infile; + int iargval; + int interrupt=0; + char *args[1000]; + + char myargs[1000][1000]; + + + string sargname, sargval; + int iline=0; + std::cout<< "config file name "<< fname << std::endl; + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + + + while (infile.good() and interrupt==0) { + sargname="none"; + sargval="0"; + getline(infile,str); + iline++; +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + if (str.find('#')!=string::npos) { +#ifdef VERBOSE + std::cout<< "Line is a comment " << std::endl; + std::cout<< str << std::endl; +#endif + continue; + } else if (str.length()<2) { +#ifdef VERBOSE + std::cout<< "Empty line " << std::endl; +#endif + continue; + } else { + istringstream ssstr(str); + iargval=0; + while (ssstr.good()) { + ssstr >> sargname; + //if (ssstr.good()) { +#ifdef VERBOSE + std::cout<< iargval << " " << sargname << std::endl; +#endif + + strcpy(myargs[iargval], sargname.c_str()); + args[iargval]=myargs[iargval]; + +#ifdef VERBOSE + std::cout<< "--" << iargval << " " << args[iargval] << std::endl; +#endif + + iargval++; + //} + } + +#ifdef VERBOSE + cout << endl; + for (int ia=0; iaexecuteLine(1,args,GET_ACTION) << std::endl; + + // single detector configuration + for (int i=0; inumberOfDetectors; i++) { + // sprintf(ext,".det%d",i); + if (detectors[i]) { + iv+=detectors[i]->writeConfigurationFile(outfile,i); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<executeLine(1,args,GET_ACTION) << std::endl; + } + + + + delete cmd; + outfile.close(); + } else { + std::cout<< "Error opening configuration file " << fname << " for writing" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "wrote " <numberOfDetectors; i++) { + + if (detectors[i]) { + n=detectors[i]->getTotalNumberOfChannels(); + if (nch_leftwriteDataFile(outfile,n, data+off, pe, pa, dataformat, choff); + fileIOStatic::writeDataFile(outfile,n, data+off, pe, pa, dataformat, choff); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); + + off+=n; + + if (pe) + pe=err+off; + + if (pa) + pa=ang+off; + + } + + } + outfile.close(); + return OK; + } else { + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; + return FAIL; + } +} + + +int multiSlsDetector::writeDataFile(string fname, int *data) { + ofstream outfile; + int choff=0, off=0; + +#ifdef VERBOSE + cout << "using overloaded multiSlsDetector function to write raw data file " << endl; +#endif + + if (data==NULL) + return FAIL; + + outfile.open (fname.c_str(),ios_base::out); + if (outfile.is_open()) + { + for (int i=0; inumberOfDetectors; i++) { + if (detectors[i]) { +#ifdef VERBOSE + cout << " write " << i << " position " << off << " offset " << choff << endl; +#endif + detectors[i]->writeDataFile(outfile, detectors[i]->getTotalNumberOfChannels(), data+off, choff); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); + off+=detectors[i]->getTotalNumberOfChannels(); + } + } + + + outfile.close(); + return OK; + } else { + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; + return FAIL; + } +} + + +int multiSlsDetector::readDataFile(string fname, double *data, double *err, double *ang, char dataformat){ + +#ifdef VERBOSE + cout << "using overloaded multiSlsDetector function to read formatted data file " << endl; +#endif + + ifstream infile; + int iline=0;//ichan, + //int interrupt=0; + string str; + int choff=0, off=0; + double *pe=err, *pa=ang; + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + + for (int i=0; inumberOfDetectors; i++) { + if (detectors[i]) { + iline+=detectors[i]->readDataFile(detectors[i]->getTotalNumberOfChannels(), infile, data+off, pe, pa, dataformat, choff); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); + off+=detectors[i]->getTotalNumberOfChannels(); + if (pe) + pe=pe+off; + if (pa) + pa=pa+off; + } + } + + + infile.close(); + } else { + std::cout<< "Could not read file " << fname << std::endl; + return -1; + } + return iline; + +} + +int multiSlsDetector::readDataFile(string fname, int *data) { + +#ifdef VERBOSE + cout << "using overloaded multiSlsDetector function to read raw data file " << endl; +#endif + + ifstream infile; + int iline=0;//ichan, + //int interrupt=0; + string str; + int choff=0, off=0; + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + + for (int i=0; inumberOfDetectors; i++) { + if (detectors[i]) { + iline+=detectors[i]->readDataFile(infile, data+off,detectors[i]->getTotalNumberOfChannels(), choff); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getMaxNumberOfChannels(); + off+=detectors[i]->getTotalNumberOfChannels(); + } + } + infile.close(); + } else { + std::cout<< "Could not read file " << fname << std::endl; + return -1; + } + return iline; +} + + + + + +//receiver + + +int multiSlsDetector::setReceiverOnline(int off) { + int ret=-100,ret1; + for (int i=0; inumberOfDetectors; i++) + if (detectors[i]){ + ret1=detectors[i]->setReceiverOnline(off); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + retval=detectors[idet]->checkReceiverOnline(); + if(!retval.empty()){ + retval1.append(retval); + retval1.append("+"); + } + } + } + return retval1; +} + + + + +string multiSlsDetector::setFilePath(string s) { + + string ret="errorerror", ret1; + //if the sls file paths are different, it should be realized by always using setfilepath even if string empty + //if(!s.empty()){ + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setFilePath(s); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setFileName(s); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setFileIndex(i); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; + + if(!threadpool){ + cout << "Error in creating threadpool. Exiting" << endl; + return FAIL; + }else{ + int* iret[posmax-posmin]; + for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ + iret[idet]= new int(OK); + Task* task = new Task(new func0_t(&slsDetector::startReceiver, + detectors[idet],iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ + if(iret[idet] != NULL){ + if(*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + }else ret = FAIL; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition>=0) { + if (detectors[i]) { + ret1=detectors[i]->startReceiver(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; + + i=thisMultiDetector->masterPosition; + if (thisMultiDetector->masterPosition>=0) { + if (detectors[i]) { + ret1=detectors[i]->stopReceiver(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition) && (detectors[idet])){ + iret[idet]= new int(OK); + Task* task = new Task(new func0_t(&slsDetector::stopReceiver, + detectors[idet],iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=posmin; idetmasterPosition) && (detectors[idet])){ + if(iret[idet] != NULL){ + if(*iret[idet] != OK) + ret = FAIL; + delete iret[idet]; + }else ret = FAIL; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition; + if (thisMultiDetector->masterPosition>=0) { + if (detectors[i]) { + s1=detectors[i]->startReceiverReadout(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; i++) { + if (detectors[i]) { + s=detectors[i]->startReceiverReadout(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition>=0) + if (detectors[thisMultiDetector->masterPosition]){ + s = detectors[thisMultiDetector->masterPosition]->getReceiverStatus(); + if(detectors[thisMultiDetector->masterPosition]->getErrorMask()) + setErrorMask(getErrorMask()|(1<masterPosition)); + return s; + } + + // if (detectors[0]) s=detectors[0]->getReceiverStatus(); + + for (int i=0; inumberOfDetectors; i++) { + s1=detectors[i]->getReceiverStatus(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors>10) { + if (detectors[0]){ + ret =detectors[0]->getFramesCaughtByReceiver(); + if(detectors[0]->getErrorMask()) + setErrorMask(getErrorMask()|(1<<0)); + } + return ret; + } + + for (int i=0; inumberOfDetectors; i++) + if (detectors[i]){ + ret1+=detectors[i]->getFramesCaughtByReceiver(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors) + return ret; + ret=(int)(ret1/thisMultiDetector->numberOfDetectors); + + return ret; +} + + + +int multiSlsDetector::getReceiverCurrentFrameIndex() { + int ret=0,ret1=0; + for (int i=0; inumberOfDetectors; i++) + if (detectors[i]){ + ret1+=detectors[i]->getReceiverCurrentFrameIndex(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors) + return ret; + ret=(int)(ret1/thisMultiDetector->numberOfDetectors); + + return ret; +} + + + +int multiSlsDetector::resetFramesCaught() { + int ret=-100, ret1; + + for (int i=0; inumberOfDetectors; i++){ + if (detectors[i]){ + ret1=detectors[i]->resetFramesCaught(); + if(detectors[i]->getErrorMask()) + setErrorMask(getErrorMask()|(1<dataBytes)/sizeof(int); + if(nel <= 0){ + cout << "Multislsdetector databytes not valid :" << thisMultiDetector->dataBytes << endl; + acquisitionIndex = -1; + return NULL; + } + int n,complete=OK; + int i,k,offsetX, offsetY, maxX, maxY; double dr; + int* retval=new int[nel]; + int *retdet = NULL, *p=retval; + string fullFName=""; + string ext=""; + int index=-1,f_index=-1,p_index=-1,det_index=-1; + double sv0=-1,sv1=-1; + + if(getDetectorsType() == EIGER){ + maxX = thisMultiDetector->numberOfChannel[X]; + maxY = thisMultiDetector->numberOfChannel[Y]; + } + + + for (int id=0; idnumberOfDetectors; id++) { + if (detectors[id]) { + n=detectors[id]->getDataBytes(); + retdet=detectors[id]->readFrameFromReceiver(fName, acquisitionIndex, frameIndex, subFrameIndex); + if(detectors[id]->getErrorMask()) + setErrorMask(getErrorMask()|(1<getDataBytes(); + if(getDetectorsType() == EIGER){ + //cout << "fname:"<getMaxNumberOfChannels()<<" n:"<getMaxNumberOfChannels(); + k=(int)(detectors[id]->getMaxNumberOfChannels(X)*dr);//bit mode + //cout << "dr:"<offsetY[id] + detectors[id]->getMaxNumberOfChannels(Y))) * maxX)*dr);//bit mode + offsetX = (int)(thisMultiDetector->offsetX[id]*dr); + //cout << "offsetY"<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->lockReceiver(lock); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + s=detectors[idet]->getReceiverLastClientIP(); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + iv=detectors[idet]->exitReceiver(); + if (iv==OK) + ival=iv; + } + } + return ival; +} + + + +int multiSlsDetector::enableWriteToFile(int enable){ + int ret=-100, ret1; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->enableWriteToFile(enable); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->overwriteFile(enable); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setFrameIndex(index); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) { + if (detectors[idet]) { + //if the detector has error + if(multiMask&(1<getErrorMask(); +#ifdef VERYVERBOSE + //append sls det error mask + sprintf(sNumber,"0x%x",slsMask); + retval.append("Error Mask " + string(sNumber)+string("\n")); +#endif + //get the error critical level + if((slsMask>0xFFFFFFFF)|critical) + critical = 1; + //append error message + retval.append(errorDefs::getErrorMessage(slsMask)); + + } + } + } + } + return retval; +} + + +int64_t multiSlsDetector::clearAllErrorMask(){ + clearErrorMask(); + clearNotAddedList(); + for (int idet=0; idetnumberOfDetectors; idet++) + if (detectors[idet]) + detectors[idet]->clearErrorMask(); + + return getErrorMask(); +} + + + +int multiSlsDetector::calibratePedestal(int frames){ + int ret=-100, ret1; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->calibratePedestal(frames); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<receiver_read_freq; + + for (int idet=0; idetnumberOfDetectors; idet++) { + if (detectors[idet]) { + ret1=detectors[idet]->setReadReceiverFrequency(getFromReceiver,i); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<receiver_read_freq = ret; + + return ret; +} + + + +int multiSlsDetector::enableReceiverCompression(int i){ + int ret=-100,ret1; + for (int idet=0; idetnumberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->enableReceiverCompression(i); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->enableTenGigabitEthernet(i); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->setReceiverFifoDepth(i); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<0) { + while (fread(&word, sizeof(word), 1,fd)) { + for (int idet=0; idetnumberOfDetectors; idet++) + if (detectors[idet]){ + detectors[idet]->setCTBWord(addr,word); + } + // cout << hex << addr << " " << word << dec << endl; + addr++; + } + + fclose(fd); + } else + return -1; + + + + + + return addr; + +} + + + /** Writes a pattern word to the CTB + @param addr address of the word, -1 is I/O control register, -2 is clk control register + @param word 64bit word to be written, -1 gets + @returns actual value + */ +uint64_t multiSlsDetector::setCTBWord(int addr,uint64_t word) { + uint64_t ret=-100,ret1; + for (int idet=0; idetnumberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->setCTBWord(addr, word); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ +int multiSlsDetector::setCTBPatLoops(int level,int &start, int &stop, int &n) { + + + int ret=-100,ret1; + for (int idet=0; idetnumberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->setCTBPatLoops(level, start, stop, n); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->setCTBPatWaitAddr(level, addr); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors; idet++) + if (detectors[idet]){ + ret1=detectors[idet]->setCTBPatWaitTime(level,t); + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + iret[idet]= new int(-1); + Task* task = new Task(new func3_t (&slsDetector::pulsePixel, + detectors[idet],n,x,y,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if (ret==-100) + ret=*iret[idet]; + else if (ret!=*iret[idet]) + ret=-1; + delete iret[idet]; + }else ret=-1; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + iret[idet]= new int(-1); + Task* task = new Task(new func3_t (&slsDetector::pulsePixelNMove, + detectors[idet],n,x,y,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if (ret==-100) + ret=*iret[idet]; + else if (ret!=*iret[idet]) + ret=-1; + delete iret[idet]; + }else ret=-1; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<numberOfDetectors]; + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + iret[idet]= new int(-1); + Task* task = new Task(new func1_t (&slsDetector::pulseChip, + detectors[idet],n,iret[idet])); + threadpool->add_task(task); + } + } + threadpool->wait_for_tasks_to_complete(); + for(int idet=0; idetnumberOfDetectors; idet++){ + if(detectors[idet]){ + if(iret[idet] != NULL){ + if (ret==-100) + ret=*iret[idet]; + else if (ret!=*iret[idet]) + ret=-1; + delete iret[idet]; + }else ret=-1; + if(detectors[idet]->getErrorMask()) + setErrorMask(getErrorMask()|(1<acquiringFlag = b; +} + +bool multiSlsDetector::getAcquiringFlag(){ + return thisMultiDetector->acquiringFlag; +} diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h new file mode 100644 index 000000000..07c4fe839 --- /dev/null +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetector.h @@ -0,0 +1,1388 @@ +/******************************************************************* + +Date: $Date$ +Revision: $Rev$ +Author: $Author$ +URL: $URL$ +ID: $Id$ + +********************************************************************/ + + + +#ifndef MULTI_SLS_DETECTOR_H +#define MULTI_SLS_DETECTOR_H + +#include "slsDetectorUtils.h" + +class slsDetector; +class ThreadPool; + +//#include "sls_detector_defs.h" + + + +//using namespace std; + + + +/** + * + * + @libdoc The multiSlsDetector class is used to operate several slsDetectors in parallel. + * + * @short This is the base class for multi detector system functionalities + * @author Anna Bergamaschi + * @version 0.1alpha + +*/ + +class multiSlsDetector : public slsDetectorUtils { + + //public virtual slsDetectorUtils { + + + typedef struct sharedMultiSlsDetector { + + + + + /** already existing flag. If the detector does not yet exist (alreadyExisting=0) the sharedMemory will be created, otherwise it will simly be linked */ + int alreadyExisting; + + + /** last process id accessing the shared memory */ + pid_t lastPID; + + + /** online flag - is set if the detector is connected, unset if socket connection is not possible */ + int onlineFlag; + + + /** stopped flag - is set if an acquisition error occurs or the detector is stopped manually. Is reset to 0 at the start of the acquisition */ + int stoppedFlag; + + + /** Number of detectors operated at once */ + int numberOfDetectors; + + /** Ids of the detectors to be operated at once */ + int detectorIds[MAXDET]; + + + /** Detectors offset in the X direction (in number of channels)*/ + int offsetX[MAXDET]; + /** Detectors offsets in the Y direction (in number of channels) */ + int offsetY[MAXDET]; + + /** position of the master detector */ + int masterPosition; + + /** type of synchronization between detectors */ + synchronizationMode syncMode; + + /** size of the data that are transfered from all detectors */ + int dataBytes; + + /** total number of channels for all detectors */ + int numberOfChannels; + + /** total number of channels for all detectors in one dimension*/ + int numberOfChannel[2]; + + /** total number of channels for all detectors */ + int maxNumberOfChannels; + + /** max number of channels for all detectors in one dimension*/ + int maxNumberOfChannel[2]; + + /** max number of channels allowed for the complete set of detectors in one dimension */ + int maxNumberOfChannelsPerDetector[2]; + + /** timer values */ + int64_t timerValue[MAX_TIMERS]; // needed?!?!?!? + + /** detector settings (standard, fast, etc.) */ + detectorSettings currentSettings; // needed?!?!?!? + /** detector threshold (eV) */ + int currentThresholdEV; // needed?!?!?!? + + + /** indicator for the acquisition progress - set to 0 at the beginning of the acquisition and incremented every time that the data are written to file */ + int progressIndex; + /** total number of frames to be acquired */ + int totalProgress; + + /** current index of the output file */ + int fileIndex; + /** name root of the output files */ + char fileName[MAX_STR_LENGTH]; + /** path of the output files */ + char filePath[MAX_STR_LENGTH]; + /** max frames per file */ + int framesPerFile; + + /** corrections to be applied to the data \see ::correctionFlags */ + int correctionMask; + /** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */ + int threadedProcessing; + /** dead time (in ns) for rate corrections */ + double tDead; + + + + /** directory where the flat field files are stored */ + char flatFieldDir[MAX_STR_LENGTH]; + /** file used for flat field corrections */ + char flatFieldFile[MAX_STR_LENGTH]; + + + /** file with the bad channels */ + char badChanFile[MAX_STR_LENGTH]; + + + /** angular conversion file */ + char angConvFile[MAX_STR_LENGTH]; + + + + + + + + /** array of angular conversion constants for each module \see ::angleConversionConstant */ + //angleConversionConstant angOff[MAXMODS]; + /** angular direction (1 if it corresponds to the encoder direction i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */ + int angDirection; + /** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */ + double fineOffset; + /** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */ + double globalOffset; + /** bin size for data merging */ + double binSize; + + + + //X and Y displacement + double sampleDisplacement[2]; + + /** number of positions at which the detector should acquire */ + int numberOfPositions; + /** list of encoder positions at which the detector should acquire */ + double detPositions[MAXPOS]; + + + + + + + /** Scans and scripts */ + + int actionMask; + + //int actionMode[MAX_ACTIONS]; + mystring actionScript[MAX_ACTIONS]; + mystring actionParameter[MAX_ACTIONS]; + + + int scanMode[MAX_SCAN_LEVELS]; + mystring scanScript[MAX_SCAN_LEVELS]; + mystring scanParameter[MAX_SCAN_LEVELS]; + int nScanSteps[MAX_SCAN_LEVELS]; + mysteps scanSteps[MAX_SCAN_LEVELS]; + int scanPrecision[MAX_SCAN_LEVELS]; + + /* Receiver read frequency */ + int receiver_read_freq; + + /** flag for acquiring */ + bool acquiringFlag; + + }; + + + + + + + + + + + + + + + + + public: + + + + using slsDetectorUtils::flatFieldCorrect; + using slsDetectorUtils::rateCorrect; + using slsDetectorUtils::setBadChannelCorrection; + using slsDetectorUtils::readAngularConversion; + using slsDetectorUtils::writeAngularConversion; + + /* + @short Structure allocated in shared memory to store detector settings and be accessed in parallel by several applications (take care of possible conflicts!) + + */ + + + /** (default) constructor + \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently + + + */ + multiSlsDetector(int id=0); + //slsDetector(string const fname); + /** destructor */ + virtual ~multiSlsDetector(); + + /** + * Creates all the threads in the threadpool + \returns OK or FAIL + */ + int createThreadPool(); + + /** destroys all the threads in the threadpool */ + void destroyThreadPool(); + + /** frees the shared memory occpied by the sharedMultiSlsDetector structure */ + int freeSharedMemory() ; + + /** allocates the shared memory occpied for the sharedMultiSlsDetector structure */ + int initSharedMemory(int) ; + + /** adds the detector with ID id in postion pos + \param id of the detector to be added (should already exist!) + \param pos position where it should be added (normally at the end of the list (default to -1) + \return the actual number of detectors or -1 if it failed*/ + int addSlsDetector(int id, int pos=-1); + + /** adds the detector with ID id in postion pos + \param name of the detector to be added (should already exist in shared memory or at least be online) + \param pos position where it should be added (normally at the end of the list (default to -1) + \return the actual number of detectors or -1 if it failed*/ + int addSlsDetector(const char *name, int pos=-1); + + int addSlsDetector(detectorType type, int pos=-1); + + /**removes the detector in position pos from the multidetector + \param pos position of the detector to be removed from the multidetector system (defaults to -1 i.e. last detector) + \returns the actual number of detectors + */ + int removeSlsDetector(int pos=-1); + + /**removes the detector in position pos from the multidetector + \param name is the name of the detector + \returns the actual number of detectors + */ + int removeSlsDetector(char *name); + + + + + string setHostname(const char*, int pos=-1); + + + string getHostname(int pos=-1); + using slsDetectorBase::getDetectorType; + + string getDetectorType(){return sgetDetectorsType();}; + + detectorType getDetectorsType(int pos=-1); + detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){addSlsDetector(type, pos); return getDetectorsType(pos);}; + + string sgetDetectorsType(int pos=-1); + string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(setDetectorsType(type, pos));}; // + string ssetDetectorsType(string s, int pos=-1);//{return getDetectorType(setDetectorsType(getDetectorType(s),pos));}; // should decode detector type + + + /** adds a detector by id in position pos + \param ival detector id to be added + \param pos position to add it (-1 fails) + \returns detector ID or -1 if detector in position i is empty + */ + int setDetectorId(int ival, int pos=-1); + + + + /** returns the id of the detector in position i + \param i position of the detector + \returns detector ID or -1 if detector in position i is empty*/ + int getDetectorId(int i); + + + /** returns the number of detectors in the multidetector structure + \returns number of detectors */ + int getNumberOfDetectors() {return thisMultiDetector->numberOfDetectors;}; + + int getMaxMods(); + int getNMods(); + int getMaxMod(dimension d); + int getNMod(dimension d); + + int getChansPerMod(int imod=0); + + angleConversionConstant *getAngularConversionPointer(int imod=0); + + + int getTotalNumberOfChannels(); + + int getTotalNumberOfChannels(dimension d); + + int getMaxNumberOfChannels(); + + int getMaxNumberOfChannels(dimension d); + + int getMaxNumberOfChannelsPerDetector(dimension d){return thisMultiDetector->maxNumberOfChannelsPerDetector[d];}; + + int setMaxNumberOfChannelsPerDetector(dimension d,int i){thisMultiDetector->maxNumberOfChannelsPerDetector[d]=i; return thisMultiDetector->maxNumberOfChannelsPerDetector[d];}; + + double getScanStep(int index, int istep){return thisMultiDetector->scanSteps[index][istep];}; + /** returns the detector offset (in number of channels) + \param pos position of the detector + \param ox reference to the offset in x + \param oy reference to the offset in y + \returns OK/FAIL if the detector does not exist + */ + int getDetectorOffset(int pos, int &ox, int &oy); + + /** sets the detector offset (in number of channels) + \param pos position of the detector + \param ox offset in x (-1 does not change) + \param oy offset in y (-1 does not change) + \returns OK/FAIL if the detector does not exist + */ + int setDetectorOffset(int pos, int ox=-1, int oy=-1); + + + + /** sets the detector in position i as master of the structure (e.g. it gates the other detectors and therefore must be started as last.
Assumes that signal 0 is gate in, signal 1 is trigger in, signal 2 is gate out + \param i position of master (-1 gets, -2 unset) + \return master's position (-1 none) + */ + int setMaster(int i=-1); + + /** + Sets/gets the synchronization mode of the various detectors + \param sync syncronization mode + \returns current syncronization mode + */ + /* enum synchronizationMode { */ + /* GET_SYNCHRONIZATION_MODE=-1, /\**< the multidetector will return its synchronization mode *\/ */ + /* NONE, /\**< all detectors are independent (no cabling) *\/ */ + /* MASTER_GATES, /\**< the master gates the other detectors *\/ */ + /* MASTER_TRIGGERS, /\**< the master triggers the other detectors *\/ */ + /* SLAVE_STARTS_WHEN_MASTER_STOPS /\**< the slave acquires when the master finishes, to avoid deadtime *\/ */ + /* }; */ + + synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); + + + /** sets the onlineFlag + \param off can be: GET_ONLINE_FLAG, returns wether the detector is in online or offline state; OFFLINE_FLAG, detector in offline state (i.e. no communication to the detector - using only local structure - no data acquisition possible!); ONLINE_FLAG detector in online state (i.e. communication to the detector updating the local structure) + \returns online/offline status + */ + int setOnline(int const online=GET_ONLINE_FLAG); + + /** checks if each of the detectors are online + \returns online/offline status and -1 if any of the detector's online status is different from the other + */ + string checkOnline(); + + /** @short activates the detector (detector specific) + \param enable can be: -1 returns wether the detector is in active (1) or inactive (0) state + \returns 0 (inactive) or 1 (active) + */ + int activate(int const enable=GET_ONLINE_FLAG); + + /** + \returns 1 if the detector structure has already be initlialized with the given id and belongs to this multiDetector instance, 0 otherwise */ + int exists(); + + + /** + Prints receiver configuration + \returns OK or FAIL + */ + int printReceiverConfiguration(); + + /** + Purely virtual function + Should be implemented in the specific detector class + /sa mythenDetector::readConfigurationFile + */ + + int readConfigurationFile(string const fname); + /** + Purely virtual function + Should be implemented in the specific detector class + /sa mythenDetector::writeConfigurationFile + */ + int writeConfigurationFile(string const fname); + + + + /* I/O */ + + + + /* Communication to server */ + + // Expert Initialization functions + + /** + get threshold energy + \param imod module number (-1 all) + \returns current threshold value for imod in ev (-1 failed) + */ + int getThresholdEnergy(int imod=-1); + + /** + set threshold energy + \param e_eV threshold in eV + \param imod module number (-1 all) + \param isettings ev. change settings + \returns current threshold value for imod in ev (-1 failed) + */ + int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS); + + /** + get detector settings + \param imod module number (-1 all) + \returns current settings + */ + detectorSettings getSettings(int imod=-1); + + /** + set detector settings + \param isettings settings + \param imod module number (-1 all) + \returns current settings + + in this function trimbits and calibration files are searched in the trimDir and calDir directories and the detector is initialized + */ + detectorSettings setSettings(detectorSettings isettings, int imod=-1); + + + /** + Returns the trimbits from the detector's shared memmory + \param retval is the array with the trimbits + \param fromDetector is true if the trimbits shared memory have to be uploaded from detector + \returns the total number of channels for the detector + */ + int getChanRegs(double* retval,bool fromDetector); + + + + + int64_t getId(idMode mode, int imod=0); + int digitalTest(digitalTestMode mode, int imod=0); + int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); + const char *getSettingsFile(); + + + int decodeNMod(int i, int &idet, int &imod); + + + /** loads the modules settings/trimbits reading from a file - file name extension is automatically generated! */ + int loadSettingsFile(string fname, int nmod=0); + + /** gets the modules settings/trimbits and writes them to file - file name extension is automatically generated! */ + int saveSettingsFile(string fname, int nmod=0); + + + /** sets all the trimbits to a particular value + \param val trimbit value + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int setAllTrimbits(int val, int imod=-1); + + + /** loads the modules calibration data reading from a file - file name extension is automatically generated! */ + int loadCalibrationFile(string fname, int nmod=0); + + /** gets the modules calibration data and writes them to file - file name extension is automatically generated! */ + int saveCalibrationFile(string fname, int nmod=0); + + + + + + + + + + + + + + + + + + + + // Acquisition functions + + + /** + start detector acquisition (master is started as last) + \returns OK if all detectors are properly started, FAIL otherwise + */ + int startAcquisition(); + + /** + stop detector acquisition (master firtst) + \returns OK/FAIL + */ + int stopAcquisition(); + + /** + start readout (without exposure or interrupting exposure) (master first) + \returns OK/FAIL + */ + int startReadOut(); + + + + /** + start detector acquisition and read all data putting them a data queue + \returns pointer to the front of the data queue + \sa startAndReadAllNoWait getDataFromDetector dataQueue + */ + int* startAndReadAll(); + + /** + start detector acquisition and read out, but does not read data from socket + + */ + int startAndReadAllNoWait(); + + /** + receives a data frame from the detector socket + \returns pointer to the data or NULL. If NULL disconnects the socket + \sa getDataFromDetector + */ + //int* getDataFromDetectorNoWait(); + /** + receives a data frame from the detector socket + \returns pointer to the data or NULL. If NULL disconnects the socket + \sa getDataFromDetector + */ + int* getDataFromDetector(); + + /** + asks and receives a data frame from the detector and puts it in the data queue + \returns pointer to the data or NULL. + \sa getDataFromDetector + */ + int* readFrame(); + + /** + asks and receives all data from the detector and puts them in a data queue + \returns pointer to the front of the queue or NULL. + \sa getDataFromDetector dataQueue + */ + int* readAll(); + + + /** + pops the data from the data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa dataQueue + */ + int* popDataQueue(); + + /** + pops the data from thepostprocessed data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa finalDataQueue + */ + detectorData* popFinalDataQueue(); + + + + + /** + resets the raw data queue + \sa dataQueue + */ + void resetDataQueue(); + + /** + resets the postprocessed data queue + \sa finalDataQueue + */ + void resetFinalDataQueue(); + + + + + + + + int setSpeed(speedVariable sp, int value=-1); + + + /** + set/get timer value + \param index timer index + \param t time in ns or number of...(e.g. frames, gates, probes) + \returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t setTimer(timerIndex index, int64_t t=-1); + /** + set/get timer value + \param index timer index + \param t time in ns or number of...(e.g. frames, gates, probes) + \returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t getTimeLeft(timerIndex index); + + /* /\** */ + /* get current timer value */ + /* \param index timer index */ + /* \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) */ + /* *\/ */ + /* int64_t getTimeLeft(timerIndex index); */ + + + + // Flags + /** + set/get dynamic range and updates the number of dataBytes + \param n dynamic range (-1 get) + \param pos detector position (-1 all detectors) + \returns current dynamic range + updates the size of the data expected from the detector + \sa sharedSlsDetector + */ + int setDynamicRange(int n, int pos); + + int getDataBytes(); + + /** + decodes which detector and the corresponding channel numbers for it + \param offsetX channel number or total channel offset in x direction + \param offsetY channel number or total channel offset in y direction + \param channelX channel number from detector offset in x direction + \param channelY channel number from detector offset in x direction + \returns detector id or -1 if channel number out of range + */ + int decodeNChannel(int offsetX, int offsetY, int &channelX, int &channelY); + +/** + verifies that min is less than max + \param n number of rois + \param r array of rois + */ + void verifyMinMaxROI(int n, ROI r[]); + + /** + set roi + \param n number of rois + \param roiLimits array of roi + \returns success or failure + */ + int setROI(int n=-1,ROI roiLimits[]=NULL); + + /** + get roi from each detector and convert it to the multi detector scale + \param n number of rois + \returns an array of multidetector's rois + */ + ROI* getROI(int &n); + + + //Corrections + + + /** + set flat field corrections + \param fname name of the flat field file (or "" if disable) + \returns 0 if disable (or file could not be read), >0 otherwise + */ + int setFlatFieldCorrection(string fname=""); + + /** + set flat field corrections + \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) + \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) + \returns 0 if ff correction disabled, >0 otherwise + */ + int setFlatFieldCorrection(double *corr, double *ecorr=NULL); + + /** + get flat field corrections + \param corr if !=NULL will be filled with the correction coefficients + \param ecorr if !=NULL will be filled with the correction coefficients errors + \returns 0 if ff correction disabled, >0 otherwise + */ + int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL); + + + + + + + + + /** + set rate correction + \param t dead time in ns - if 0 disable correction, if >0 set dead time to t, if <0 set deadtime to default dead time for current settings + \returns 0 if rate correction disabled, >0 otherwise + */ + int setRateCorrection(double t=0); + + + /** + get rate correction + \param t reference for dead time + \returns 0 if rate correction disabled, >0 otherwise + */ + int getRateCorrection(double &t); + + + /** + get rate correction tau + \returns 0 if rate correction disabled, otherwise the tau used for the correction + */ + double getRateCorrectionTau(); + /** + get rate correction + \returns 0 if rate correction disabled, >0 otherwise + */ + int getRateCorrection(); + + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(string fname=""); + + + int setBadChannelCorrection(int nch, int *chs, int ff); + + + + /** + get bad channels correction + \param bad pointer to array that if bad!=NULL will be filled with the bad channel list + \returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + int getBadChannelCorrection(int *bad=NULL); + + + + /** + pure virtual function + get angular conversion + \param reference to diffractometer direction + \param angconv array that will be filled with the angular conversion constants + \returns 0 if angular conversion disabled, >0 otherwise + \sa mythenDetector::getAngularConversion + */ + /////////////////////////////////////////////////// virtual int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL); + + + + int readAngularConversionFile(string fname); + + int writeAngularConversion(string fname); + + // double* convertAngles(double pos); + + + + + /** + decode data from the detector converting them to an array of doubles, one for each channle + \param datain data from the detector + \returns pointer to a double array with a data per channel + */ + double* decodeData(int *datain, double *fdata=NULL); + + + + + /** + flat field correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param ffcoefficient flat field correction coefficient + \param fferr erro on ffcoefficient + \returns 0 + */ + // int flatFieldCorrect(double datain, double errin, double &dataout, double &errout, double ffcoefficient, double fferr); + + /** + flat field correct data + \param datain data array + \param errin error array on data (if NULL will default to sqrt(datain) + \param dataout array of corrected data + \param errout error on corrected data (if not NULL) + \returns 0 + */ + int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); + + + + /** + rate correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param tau dead time 9in ns) + \param t acquisition time (in ns) + \returns 0 + */ + // int rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t); + + /** + rate correct data + \param datain data array + \param errin error array on data (if NULL will default to sqrt(datain) + \param dataout array of corrected data + \param errout error on corrected data (if not NULL) + \returns 0 + */ + int rateCorrect(double* datain, double *errin, double* dataout, double *errout); + + /** + turns off server + */ + int exitServer(); + + /** pure /////////////////////////////////////////////////// virtual function + function for processing data + /param delflag if 1 the data are processed, written to file and then deleted. If 0 they are added to the finalDataQueue + \sa mythenDetector::processData + */ + /////////////////////////////////////////////////// virtual void* processData(int delflag=1); // thread function + + + /////////////////////////////////////////////////// virtual void acquire(int delflag=1); + + /** calcualtes the total number of steps of the acquisition. + called when number of frames, number of cycles, number of positions and scan steps change + */ + /////////////////////////////////////// int setTotalProgress(); ////////////// from slsDetectorUtils! + + /** returns the current progress in % */ + ////////////////////////////////double getCurrentProgress();////////////// from slsDetectorUtils! + + + /** + set dacs value + \param val value (in V) + \param index DAC index + \param mV 0 in dac units or 1 in mV + \param imod module number (if -1 alla modules) + \returns current DAC value + */ + dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); + + /** + set dacs value + \param val value (in V) + \param index DAC index + \param imod module number (if -1 alla modules) + \returns current DAC value + */ + dacs_t getADC(dacIndex index, int imod=0); + /** + configure channel + \param reg channel register + \param ichan channel number (-1 all) + \param ichip chip number (-1 all) + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_channel + */ + int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); + /** + pure virtual function + get angular conversion + \param reference to diffractometer direction + \param angconv array that will be filled with the angular conversion constants + \returns 0 if angular conversion disabled, >0 otherwise + \sa mythenDetector::getAngularConversion + */ + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; + + + + /** + get run status + \returns status mask + */ + //virtual runStatus getRunStatus()=0; + runStatus getRunStatus(); + + + + + + /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ + char* getSettingsDir(); + /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ + char* setSettingsDir(string s); + /** + returns the location of the calibration files + \sa sharedSlsDetector + */ + char* getCalDir(); + /** + sets the location of the calibration files + \sa sharedSlsDetector + */ + char* setCalDir(string s); + + + char *getNetworkParameter(networkParameter); + char *setNetworkParameter(networkParameter, std::string); + int setPort(portType, int); + int lockServer(int); + + string getLastClientIP(); + + /** + configures mac for gotthard readout + \returns OK or FAIL + */ + int configureMAC(); + + int setNumberOfModules(int i=-1, dimension d=X); + int getMaxNumberOfModules(dimension d=X); + int setDynamicRange(int i=-1); + + + + + + int writeRegister(int addr, int val); + + + int writeAdcRegister(int addr, int val); + + + int readRegister(int addr); + + + + int setTrimEn(int nen, int *en=NULL); + int getTrimEn(int *en=NULL); + + + externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); + int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); + + + externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); + + /** + Loads dark image or gain image to the detector + \param index can be DARK_IMAGE or GAIN_IMAGE + \fname file name to load data from + \returns OK or FAIL + */ + int loadImageToDetector(imageType index,string const fname); + + /** + sets the value of s angular conversion parameter + \param c can be ANGULAR_DIRECTION, GLOBAL_OFFSET, FINE_OFFSET, BIN_SIZE + \param v the value to be set + \returns the actual value + */ + + double setAngularConversionParameter(angleConversionParameter c, double v); + + /** + + writes a data file + \param name of the file to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not write the file or data=NULL + \sa mythenDetector::writeDataFile + + */ + int writeDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1); + + + /** + + writes a data file + \param name of the file to be written + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + \sa mythenDetector::writeDataFile + */ + int writeDataFile(string fname, int *data); + + /** + + reads a data file + \param name of the file to be read + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param nch number of channels to be written to file. if <=0 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not read the file or data=NULL + + \sa mythenDetector::readDataFile + */ + int readDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); + + + /** + + reads a data file + \param name of the file to be read + \param data array of data values + \returns OK or FAIL if it could not read the file or data=NULL + \sa mythenDetector::readDataFile + */ + int readDataFile(string fname, int *data); + + + /** + writes the counter memory block from the detector + \param startACQ is 1 to start acquisition after reading counter + \param fname file name to load data from + \returns OK or FAIL + */ + int writeCounterBlockFile(string const fname,int startACQ=0); + + + /** + Resets counter in detector + \param startACQ is 1 to start acquisition after resetting counter + \returns OK or FAIL + */ + int resetCounterBlock(int startACQ=0); + + /** set/get counter bit in detector + * @param i is -1 to get, 0 to reset and any other value to set the counter bit + /returns the counter bit in detector + */ + int setCounterBit(int i = -1); + + + int getMoveFlag(int imod); + + + slsDetector *getSlsDetector(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;}; + + + + //receiver + + /** + calls setReceiverTCPSocket if online and sets the flag + */ + int setReceiverOnline(int const online=GET_ONLINE_FLAG); + + /** + Checks if the receiver is really online + */ + string checkReceiverOnline(); + + + /** + Sets up the file directory + @param s file directory + \returns file dir + */ + string setFilePath(string s=""); + + /** + Sets up the file name + @param s file name + \returns file name + */ + string setFileName(string s=""); + + /** + Sets up the file index + @param i file index + \returns file index + */ + int setFileIndex(int i=-1); + + /** + \returns file dir + */ + string getFilePath(){return setFilePath();}; + + /** + \returns file name + */ + string getFileName(){return setFileName();}; + + /** + \returns file index + */ + int getFileIndex(){return setFileIndex();}; + + + /** Starts the listening mode of receiver + \returns OK or FAIL + */ + int startReceiver(); + + /** Stops the listening mode of receiver + \returns OK or FAIL + */ + int stopReceiver(); + + /** Sets the receiver to start any readout remaining in the fifo and + * change status to transmitting. + * The status changes to run_finished when fifo is empty + */ + runStatus startReceiverReadout(); + + /** gets the status of the listening mode of receiver + \returns status + */ + runStatus getReceiverStatus(); + + /** gets the number of frames caught by receiver + \returns number of frames caught by receiver + */ + int getFramesCaughtByReceiver(); + + /** gets the current frame index of receiver + \returns current frame index of receiver + */ + int getReceiverCurrentFrameIndex(); + + /** + * resets framescaught + * @param index frames caught by receiver + */ + int resetFramesCaught(); + + /** + * Reads a frame from receiver + * @param fName file name of current frame() + * @param acquisitionIndex current acquisition index + * @param frameIndex current frame index (for each scan) + * @param subFrameIndex current sub frame index (for 32 bit mode for eiger) + /returns a frame read from recever + */ + int* readFrameFromReceiver(char* fName, int &acquisitionIndex, int &frameIndex, int &subFrameIndex); + + /** Locks/Unlocks the connection to the receiver + /param lock sets (1), usets (0), gets (-1) the lock + /returns lock status of the receiver + */ + int lockReceiver(int lock=-1); + + /** + Returns the IP of the last client connecting to the receiver + */ + string getReceiverLastClientIP(); + + /** + Turns off the receiver server! + */ + int exitReceiver(); + + /** + Sets/Gets receiver file write enable + @param enable 1 or 0 to set/reset file write enable + /returns file write enable + */ + int enableWriteToFile(int enable=-1); + + /** + Sets/Gets file overwrite enable + @param enable 1 or 0 to set/reset file overwrite enable + /returns file overwrite enable + */ + int overwriteFile(int enable=-1); + + /** + * set frame index to 0 or -1 + * @param index is the frame index + */ + int setFrameIndex(int index=-1); + + + + + int fillModuleMask(int *mM); + + /**checks error mask and returns error message if it exists + * @param myDet is the multidetector object + * @param critical is 1 if any of the messages is critical + /returns error message else an empty string + */ + string getErrorMessage(int &critical); + + /** Clears error mask of both multi and sls + /returns error mask + */ + int64_t clearAllErrorMask(); + + /** Starts acquisition, calibrates pedestal and writes to fpga + /returns number of frames + */ + int calibratePedestal(int frames = 0); + + /** Sets the read receiver frequency + if Receiver read upon gui request, readRxrFrequency=0, + else every nth frame to be sent to gui + @param getFromReceiver is 1 if it should ask the receiver, + 0 if it can get it from multislsdetecter + @param i is the receiver read frequency + /returns read receiver frequency + */ + int setReadReceiverFrequency(int getFromReceiver, int i=-1); + + /** updates the multidetector offsets */ + void updateOffsets(); + + /** enable/disable or get data compression in receiver + * @param i is -1 to get, 0 to disable and 1 to enable + /returns data compression in receiver + */ + int enableReceiverCompression(int i = -1); + + /** enable/disable or 10Gbe + * @param i is -1 to get, 0 to disable and 1 to enable + /returns if 10Gbe is enabled + */ + int enableTenGigabitEthernet(int i = -1); + + /** set/get receiver fifo depth + * @param i is -1 to get, any other value to set the fifo deph + /returns the receiver fifo depth + */ + int setReceiverFifoDepth(int i = -1); + + + + /******** CTB funcs */ + + /** opens pattern file and sends pattern to CTB + @param fname pattern file to open + @returns OK/FAIL + */ + int setCTBPattern(string fname); + + + /** Writes a pattern word to the CTB + @param addr address of the word, -1 is I/O control register, -2 is clk control register + @param word 64bit word to be written, -1 gets + @returns actual value + */ + uint64_t setCTBWord(int addr,uint64_t word=-1); + + /** Sets the pattern or loop limits in the CTB + @param level -1 complete pattern, 0,1,2, loop level + @param start start address if >=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ + int setCTBPatLoops(int level,int &start, int &stop, int &n); + + + /** Sets the wait address in the CTB + @param level 0,1,2, wait level + @param addr wait address, -1 gets + @returns actual value + */ + int setCTBPatWaitAddr(int level, int addr=-1); + + /** Sets the wait time in the CTB + @param level 0,1,2, wait level + @param t wait time, -1 gets + @returns actual value + */ + int setCTBPatWaitTime(int level, uint64_t t=-1); + + /** + Pulse Pixel + \param n is number of times to pulse + \param x is x coordinate + \param y is y coordinate + \returns OK or FAIL + */ + int pulsePixel(int n=0,int x=0,int y=0); + + /** + Pulse Pixel and move by a relative value + \param n is number of times to pulse + \param x is relative x value + \param y is relative y value + \returns OK or FAIL + */ + int pulsePixelNMove(int n=0,int x=0,int y=0); + + /** + Pulse Chip + \param n is number of times to pulse + \returns OK or FAIL + */ + int pulseChip(int n=0); + + /** + Set acquiring flag in shared memory + \param b acquiring flag + */ + void setAcquiringFlag(bool b=false); + + /** + Get acquiring flag from shared memory + \returns acquiring flag + */ + bool getAcquiringFlag(); + + + + + + + + + protected: + + + /** Shared memory ID */ + int shmId; + + /** pointers to the slsDetector structures */ + slsDetector *detectors[MAXDET]; + + /** Shared memory structure */ + sharedMultiSlsDetector *thisMultiDetector; + + private: + ThreadPool* threadpool; + + + +}; + + + +#endif diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorClient.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorClient.h new file mode 100644 index 000000000..8d59f13b4 --- /dev/null +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorClient.h @@ -0,0 +1,107 @@ +#include +#include + + +#include "multiSlsDetector.h" +#include "multiSlsDetectorCommand.h" + + +#include +using namespace std; + +int dummyCallback(detectorData* d, int p,void*) { + cout << "got data " << p << endl; + return 0; +}; + +class multiSlsDetectorClient { + + public: + multiSlsDetectorClient(int argc, char *argv[], int action, multiSlsDetector *myDetector=NULL) { \ + string answer; \ + multiSlsDetectorCommand *myCmd; \ + int id=-1, iv=0, pos=-1; \ + int del=0; \ + char cmd[100]; \ + if (action==slsDetectorDefs::READOUT_ACTION) { \ + + if (argc!=0) { + iv=sscanf(argv[0],"%d-%s",&id,cmd); \ + if (iv>0 && id>=0 && strchr(argv[0],'-')) { + cout << "id " << id << endl; \ + if (iv>1) + argv[0]=cmd; + } + iv=sscanf(argv[0],"%d:",&pos); \ + if (iv>0 && pos>=0 && strchr(argv[0],':')) + cout << "pos " << pos << "is not allowed!" << endl; \ + } + if (id<0) + id=0; + + if (myDetector==NULL) { \ + myDetector=new multiSlsDetector(id); \ + //myDetector->registerDataCallback(&dummyCallback, NULL); + del=1; \ + }; + // cout << "noid" <executeLine(argc, argv, action); \ + cout << answer<< endl; \ + delete myCmd; \ + if (del) delete myDetector; \ + return; \ + }; \ + if (action==slsDetectorDefs::PUT_ACTION && argc<2) { \ + cout << "Wrong usage - should be: "<< argv[0] << \ + "[id-][pos:]channel arg" << endl; \ + cout << endl; \ + return; \ + if (del) delete myDetector; \ + }; + if (action==slsDetectorDefs::GET_ACTION && argc<1) { \ + cout << "Wrong usage - should be: "<< argv[0] << \ + "[id-][pos:]channel arg" << endl; \ + cout << endl; \ + if (del) delete myDetector; \ + return; \ + }; \ + if (myDetector==NULL) { \ + iv=sscanf(argv[0],"%d-%s",&id, cmd); \ + if (iv==2 && id>=0) { \ + myDetector=new multiSlsDetector(id); \ + argv[0]=cmd; \ + cout << id << "-" ; \ + } else { \ + myDetector=new multiSlsDetector(); \ + }; \ + del=1; \ + } \ + iv=sscanf(argv[0],"%d:%s",&pos, cmd); \ + if (iv==2 && pos>=0) { \ + argv[0]=cmd; \ + cout << pos << ":" ; \ + } ; \ + myCmd=new multiSlsDetectorCommand(myDetector); \ + answer=myCmd->executeLine(argc, argv, action, pos); \ + cout << argv[0] << " " ; \ + cout << answer<< endl; \ + delete myCmd; \ + if (del) delete myDetector; \ + }; + + + + +}; + + + + + + + + + + + diff --git a/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorCommand.h b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorCommand.h new file mode 100644 index 000000000..a387046c6 --- /dev/null +++ b/slsDetectorSoftware/multiSlsDetector/multiSlsDetectorCommand.h @@ -0,0 +1,72 @@ + +#ifndef MULTI_SLS_DETECTOR_COMMAND_H +#define MULTI_SLS_DETECTOR_COMMAND_H + + +#include "slsDetector.h" +#include "multiSlsDetector.h" +#include "slsDetectorCommand.h" +using namespace std; + + +/** @short This class handles the command line I/Os, help etc. of the text clients */ + + +class multiSlsDetectorCommand : public slsDetectorCommand { + + public: + + + multiSlsDetectorCommand(multiSlsDetector *det) : slsDetectorCommand(det) {myDet=det;}; + + + /* /\** */ +/* executes a set of string arguments according to a given format. It is used to read/write configuration file, dump and retrieve detector settings and for the command line interface command parsing */ +/* \param narg number of arguments */ +/* \param args array of string arguments */ +/* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ +/* \returns answer string */ +/* *\/ */ + + string executeLine(int narg, char *args[], int action, int id=-1) { \ + string s; \ + if (id>=0) { + slsDetector *d=myDet->getSlsDetector(id); \ + if (d) { \ + slsDetectorCommand *cmd=new slsDetectorCommand(d); \ + s=cmd->executeLine(narg, args, action); \ + if(d->getErrorMask()) \ + myDet->setErrorMask((myDet->getErrorMask())|(1</dev/null diff --git a/slsDetectorSoftware/mythenDetectorServer/Makefile.dum b/slsDetectorSoftware/mythenDetectorServer/Makefile.dum new file mode 100644 index 000000000..59a15e28e --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/Makefile.dum @@ -0,0 +1,37 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + +AXIS_USABLE_LIBS = UCLIBC GLIBC +include $(AXIS_TOP_DIR)/tools/build/Rules.axis + +PROGS= dummy + +INSTDIR= $(prefix)/bin +INSTMODE= 0777 + +SRCS= dummy_main.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS= $(SRCS:%.c=%.o) + +CFLAGS+= -Wall -DC_ONLY -DVERBOSE +#-Werror + +LDLIBS+= -lm + +all: $(PROGS) + +boot: $(OBJS) + +$(PROGS): $(OBJS) + echo $(OBJS) + $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@ + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + +clean: + rm -rf $(PROGS) *.o + +depend: + makedepend -Y -- $(CFLAGS) -- $(SRCS) 2>/dev/null diff --git a/slsDetectorSoftware/mythenDetectorServer/Makefile.picasso b/slsDetectorSoftware/mythenDetectorServer/Makefile.picasso new file mode 100644 index 000000000..11e3645fd --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/Makefile.picasso @@ -0,0 +1,46 @@ +# $Id: Makefile,v 1.1.1.1 2006/02/04 03:35:01 freza Exp $ +# first compile +# make cris-axis-linux-gnu + +AXIS_USABLE_LIBS = UCLIBC GLIBC +include $(AXIS_TOP_DIR)/tools/build/Rules.axis + +PROGS= mythenDetectorServer +PICASSO= picassoDetectorServer +PICASSOFLAGS= -DPICASSOD + +INSTDIR= $(prefix)/bin +INSTMODE= 0777 + +SRCS= server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c +OBJS= $(SRCS:%.c=%.o) + +CFLAGS+= -Wall -DC_ONLY -DMCB_FUNCS -DVERBOSE -DVERYVERBOSE -DPICASSOD +#-Werror + +LDLIBS+= -lm + +picasso: $(PICASSO) +mythen: $(PROGS) +all: $(PROGS) $(PICASSO) + +boot: $(OBJS) + +$(PROGS): $(OBJS) + echo $(OBJS) + $(CC) $(LDFLAGS) $^ $(LDLIBS) $(CFLAGS) -o $@ + +$(PICASSO): $(OBJS) + echo $(OBJS) + $(CC) $(LDFLAGS) $^ $(LDLIBS) $(CFLAGS) $(PICASSOFLAGS) -o $@ + + +install: $(PROGS) + $(INSTALL) -d $(INSTDIR) + $(INSTALL) -m $(INSTMODE) $(PROGS) $(INSTDIR) + +clean: + rm -rf $(PROGS) $(PICASSO) *.o + +depend: + makedepend -Y -- $(CFLAGS) -- $(SRCS) 2>/dev/null diff --git a/slsDetectorSoftware/mythenDetectorServer/Makefile.virtual b/slsDetectorSoftware/mythenDetectorServer/Makefile.virtual new file mode 100755 index 000000000..f3cb34b21 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/Makefile.virtual @@ -0,0 +1,18 @@ +DESTDIR?= ./ +PROGS= $(DESTDIR)/mythenVirtualServer + +SRCS= server.c server_funcs.c communication_funcs.c firmware_funcs.c mcb_funcs.c trimming_funcs.c sharedmemory.c + +OBJS= $(SRCS:%.c=%.o) + +CFLAGS+= -Wall -DC_ONLY -DMCB_FUNCS -DDACS_INT $(VFLAGS) -DVIRTUAL -DVERBOSE + +LDLIBS+= -lm +mythenVirtualServer : clean $(PROGS) + +$(PROGS): $(SRCS) + gcc $(LDFLAGS) $(SRCS) $(LDLIBS) $(CFLAGS) -o $@ + +clean: + rm -f *.o $(PROGS) + diff --git a/slsDetectorSoftware/mythenDetectorServer/ansi.h b/slsDetectorSoftware/mythenDetectorServer/ansi.h new file mode 120000 index 000000000..a122db0ad --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/ansi.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/ansi.h \ No newline at end of file diff --git a/slsDetectorSoftware/mythenDetectorServer/communication_funcs.c b/slsDetectorSoftware/mythenDetectorServer/communication_funcs.c new file mode 120000 index 000000000..87a4f95d1 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/communication_funcs.c @@ -0,0 +1 @@ +../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/mythenDetectorServer/communication_funcs.h b/slsDetectorSoftware/mythenDetectorServer/communication_funcs.h new file mode 120000 index 000000000..f220903b2 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/communication_funcs.h @@ -0,0 +1 @@ +../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/mythenDetectorServer/firmware_funcs.c b/slsDetectorSoftware/mythenDetectorServer/firmware_funcs.c new file mode 100755 index 000000000..49cbdb982 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/firmware_funcs.c @@ -0,0 +1,1760 @@ +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif + +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "registers.h" + +#ifdef SHAREDMEMORY +#include "sharedmemory.h" +#endif + +#include +#include +#include + +#include + +//for memory mapping +u_int64_t CSP0BASE; + +FILE *debugfp, *datafp; + +int fr; +int wait_time; +int *fifocntrl; +int *values; +int *statusreg; +const int nModY=1; +int nModBoard; +int nModX=NMAXMOD; +int dynamicRange=32; +int dataBytes=NMAXMOD*NCHIP*NCHAN*4; +int storeInRAM=0; +int *ram_values=NULL; +char *now_ptr=NULL; +int ram_size=0; + +int64_t totalTime=1; +u_int32_t progressMask=0; + + + +int ififostart, ififostop, ififostep, ififo; + +int masterMode=NO_MASTER, syncMode=NO_SYNCHRONIZATION, timingMode=AUTO_TIMING; + +enum externalSignalFlag signals[4]={GATE_IN_ACTIVE_HIGH, TRIGGER_IN_RISING_EDGE, SIGNAL_OFF, SIGNAL_OFF}; + + +#ifdef MCB_FUNCS +extern const int nChans; +extern const int nChips; +extern const int nDacs; +extern const int nAdcs; +#endif +#ifndef MCB_FUNCS + +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +#endif + +//int mybyte; +//int mysize=dataBytes/8; + +int mapCSP0(void) { + printf("Mapping memory\n"); +#ifndef VIRTUAL + int fd; + fd = open("/dev/mem", O_RDWR | O_SYNC, 0); + if (fd == -1) { + printf("\nCan't find /dev/mem!\n"); + return FAIL; + } + printf("/dev/mem opened\n"); + CSP0BASE = (u_int32_t)mmap(0, MEM_SIZE, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, fd, CSP0); + if (CSP0BASE == (u_int32_t)MAP_FAILED) { + printf("\nCan't map memmory area!!\n"); + return FAIL; + } + printf("CSP0 mapped\n"); + +#endif +#ifdef VIRTUAL + CSP0BASE = malloc(MEM_SIZE); + printf("memory allocated\n"); +#endif +#ifdef SHAREDMEMORY + if ( (res=inism(SMSV))<0) { + printf("error attaching shared memory! %i",res); + return FAIL; + } +#endif + printf("CSPOBASE=from %08x to %x\n",CSP0BASE,CSP0BASE+MEM_SIZE); + + values=(u_int32_t*)(CSP0BASE+FIFO_DATA_REG_OFF); + printf("values=%08x\n",values); + fifocntrl=(u_int32_t*)(CSP0BASE+FIFO_CNTRL_REG_OFF); + printf("fifcntrl=%08x\n",fifocntrl); + statusreg=(u_int32_t*)(CSP0BASE+STATUS_REG); + printf("statusreg=%08x\n",statusreg); + + return OK; +} + + +u_int32_t bus_w(u_int32_t offset, u_int32_t data) { + u_int32_t *ptr1; + + + ptr1=(u_int32_t*)(CSP0BASE+offset); + *ptr1=data; + + return OK; +} + + +u_int32_t bus_r(u_int32_t offset) { + u_int32_t *ptr1; + + ptr1=(u_int32_t*)(CSP0BASE+offset); + return *ptr1; +} + +// direct pattern output +u_int32_t putout(char *s, int modnum) { + int i; + u_int32_t pat; + int addr; + + if (strlen(s)<16) { + fprintf(stdout," *** putout error: incorrect pattern length ***\n"); + fprintf(stdout," %s \n",s); + return FAIL; + } + + pat=0; + for (i=0;i<16;i++) { + if (s[i]=='1') pat=pat+(1<>CLK_DIVIDER_OFFSET); +} + +u_int32_t getClockDivider() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)&CLK_DIVIDER_MASK)>>CLK_DIVIDER_OFFSET); + return clk_div; +} + +u_int32_t setSetLength(int d) { + u_int32_t c; + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>SET_LENGTH_OFFSET); +} + +u_int32_t getSetLength() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)& SET_LENGTH_MASK)>>SET_LENGTH_OFFSET); + return clk_div; +} + + +u_int32_t setWaitStates(int d1) { + u_int32_t c; + int d=d1-2; + //int d=d1-3; + char cmd[100]; + if (d1<=0xf) { + sprintf(cmd,"bus -a 0xb0000000 -w 0x%x0008",d1); + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>WAIT_STATES_OFFSET)+2; +} + +u_int32_t getWaitStates() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)& WAIT_STATES_MASK)>>WAIT_STATES_OFFSET); + return clk_div+2; +} + + +u_int32_t setTotClockDivider(int d) { + u_int32_t c; + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>TOTCLK_DIVIDER_OFFSET); +} + +u_int32_t getTotClockDivider() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)&TOTCLK_DIVIDER_MASK)>>TOTCLK_DIVIDER_OFFSET); + return clk_div; +} + + +u_int32_t setTotDutyCycle(int d) { + u_int32_t c; + c=bus_r(SPEED_REG); + bus_w(SPEED_REG,(d<>TOTCLK_DUTYCYCLE_OFFSET); +} + +u_int32_t getTotDutyCycle() { + u_int32_t clk_div; + clk_div=((bus_r(SPEED_REG)&TOTCLK_DUTYCYCLE_MASK)>>TOTCLK_DUTYCYCLE_OFFSET); + return clk_div; +} + + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode) { + + + // int modes[]={EXT_SIG_OFF, EXT_GATE_IN_ACTIVEHIGH, EXT_GATE_IN_ACTIVELOW,EXT_TRIG_IN_RISING,EXT_TRIG_IN_FALLING,EXT_RO_TRIG_IN_RISING, EXT_RO_TRIG_IN_FALLING,EXT_GATE_OUT_ACTIVEHIGH, EXT_GATE_OUT_ACTIVELOW, EXT_TRIG_OUT_RISING, EXT_TRIG_OUT_FALLING, EXT_RO_TRIG_OUT_RISING, EXT_RO_TRIG_OUT_FALLING}; + + u_int32_t c; + // int off=d*SIGNAL_OFFSET; + c=bus_r(EXT_SIGNAL_REG); + + + + if (d>=0 && d<4) { + signals[d]=mode; +#ifdef VERBOSE + printf("settings signal variable number %d to value %04x\n", d, signals[d]); +#endif + + // if output signal, set it! + + switch (mode) { + case GATE_IN_ACTIVE_HIGH: + case GATE_IN_ACTIVE_LOW: + if (timingMode==GATE_FIX_NUMBER || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case TRIGGER_IN_RISING_EDGE: + case TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_EXPOSURE || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case RO_TRIGGER_IN_RISING_EDGE: + case RO_TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_READOUT) + setFPGASignal(d,mode); + else + setFPGASignal(d,SIGNAL_OFF); + break; + case MASTER_SLAVE_SYNCHRONIZATION: + setSynchronization(syncMode); + break; + default: + setFPGASignal(d,mode); + } + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + } + + return getExtSignal(d); +} + +u_int32_t setFPGASignal(int d, enum externalSignalFlag mode) { + + + int modes[]={SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW,TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE,RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE,RO_TRIGGER_OUT_FALLING_EDGE}; + + // int modes[]={EXT_SIG_OFF, EXT_GATE_IN_ACTIVEHIGH, EXT_GATE_IN_ACTIVELOW,EXT_TRIG_IN_RISING,EXT_TRIG_IN_FALLING,EXT_RO_TRIG_IN_RISING, EXT_RO_TRIG_IN_FALLING,EXT_GATE_OUT_ACTIVEHIGH, EXT_GATE_OUT_ACTIVELOW, EXT_TRIG_OUT_RISING, EXT_TRIG_OUT_FALLING, EXT_RO_TRIG_OUT_RISING, EXT_RO_TRIG_OUT_FALLING}; + + u_int32_t c; + int off=d*SIGNAL_OFFSET; + c=bus_r(EXT_SIGNAL_REG); + + + if (mode<=RO_TRIGGER_OUT_FALLING_EDGE && mode>=0) { +#ifdef VERBOSE + printf("writing signal register number %d mode %04x\n",d, modes[mode]); +#endif + bus_w(EXT_SIGNAL_REG,((modes[mode])<>off); */ + +/* if (mode=0 && d<4) { +#ifdef VERBOSE + printf("gettings signal variable number %d value %04x\n", d, signals[d]); +#endif + return signals[d]; + } else + return -1; + +} + + +int getFPGASignal(int d) { + + int modes[]={SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW,TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE,RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE,RO_TRIGGER_OUT_FALLING_EDGE}; + + int off=d*SIGNAL_OFFSET; + int mode=((bus_r(EXT_SIGNAL_REG)&(SIGNAL_MASK<>off); + + if (mode<=RO_TRIGGER_OUT_FALLING_EDGE) { + if (modes[mode]!=SIGNAL_OFF && signals[d]!=MASTER_SLAVE_SYNCHRONIZATION) + signals[d]=modes[mode]; +#ifdef VERBOSE + printf("gettings signal register number %d value %04x\n", d, modes[mode]); +#endif + return modes[mode]; + } else + return -1; + +} + + +/* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; +*/ + + +int setTiming(int ti) { + + + int ret=GET_EXTERNAL_COMMUNICATION_MODE; + + int g=-1, t=-1, rot=-1; + + int i; + printf("*********************************Setting timing mode %d!\n", ti); + switch (ti) { + case AUTO_TIMING: + timingMode=ti; + // disable all gates/triggers in except if used for master/slave synchronization + for (i=0; i<4; i++) { + if (getFPGASignal(i)>0 && getFPGASignal(i)=0 && t>=0 && rot<0) { + ret=GATE_WITH_START_TRIGGER; + } else if (g<0 && t>=0 && rot<0) { + ret=TRIGGER_EXPOSURE; + } else if (g>=0 && t<0 && rot<0) { + ret=GATE_FIX_NUMBER; + } else if (g<0 && t<0 && rot>0) { + ret=TRIGGER_READOUT; + } else if (g<0 && t<0 && rot<0) { + ret=AUTO_TIMING; + } + + // timingMode=ret; + + return ret; + +} + + + + +int setConfigurationRegister(int d) { +#ifdef VERBOSE + printf("Setting configuration register to %x",d); +#endif + if (d>=0) { + bus_w(CONFIG_REG,d); + } +#ifdef VERBOSE + printf("configuration register is %x", bus_r(CONFIG_REG)); +#endif + return bus_r(CONFIG_REG); +} + +int setToT(int d) { + // int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting ToT to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: ToT is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|TOT_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~TOT_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("ToT is %x\n", reg); +#endif + if (reg&TOT_ENABLE_BIT) + return 1; + else + return 0; +} + +int setContinousReadOut(int d) { + // int ret=0; + int reg; +#ifdef VERBOSE + printf("Setting Continous readout to %d\n",d); +#endif + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Before: Continous readout is %x\n", reg); +#endif + if (d>0) { + bus_w(CONFIG_REG,reg|CONT_RO_ENABLE_BIT); + } else if (d==0) { + bus_w(CONFIG_REG,reg&(~CONT_RO_ENABLE_BIT)); + } + reg=bus_r(CONFIG_REG); +#ifdef VERBOSE + printf("Continous readout is %x\n", reg); +#endif + if (reg&CONT_RO_ENABLE_BIT) + return 1; + else + return 0; +} + + +u_int64_t getMcsNumber() { + + FILE *fp=NULL; + u_int64_t res; + char line[150]; + int a[6]; + + int n=0, i; + //u_int64_t a0,a1,a2,a3,a4,a5,n=0; + fp=fopen("/etc/conf.d/mac","r"); + if (fp==NULL) { + printf("could not ope MAC file\n");; + return -1; + } + while (fgets(line,150,fp)) { + //MAC="00:40:8C:CD:00:00" + printf(line); + if (strstr(line,"MAC=")) + n=sscanf(line,"MAC=\"%x:%x:%x:%x:%x:%x\"",a+5,a+4,a+3,a+2,a+1,a); + } + fclose(fp); + if (n!=6){ + printf("could not scan MAC address\n");; + return -1; + } + res=0; + for (i=0; i=(FPGA_VERSION_VAL&0x00ffffff)) { + printf("FPGA version ok!! %06x\n",val); + } else { + printf("FPGA version too old! %06x\n",val); + return FAIL; + } + //dummy register + val=0xF0F0F0F0; + bus_w(DUMMY_REG, val); + val=bus_r(DUMMY_REG); + if (val==0xF0F0F0F0) { + printf("FPGA dummy register ok!! %x\n",val); + } else { + printf("FPGA dummy register wrong!! %x instead of 0xF0F0F0F0 \n",val); + result=FAIL; + // return FAIL; + } + //dummy register + val=0x0F0F0F0F; + bus_w(DUMMY_REG, val); + val=bus_r(DUMMY_REG); + if (val==0x0F0F0F0F) { + printf("FPGA dummy register ok!! %x\n",val); + } else { + printf("FPGA dummy register wrong!! %x instead of 0x0F0F0F0F \n",val); + result=FAIL; + // return FAIL; + } + // } + return result; +} + + +// for fpga test +u_int32_t testRAM(void) { + int result=OK; + int i=0; + allocateRAM(); + // while(i<100000) { + memcpy(ram_values, values, dataBytes); + printf ("%d: copied fifo %x to memory %x size %d\n",i++, values, ram_values, dataBytes); + // } + return result; +} + +int getNModBoard() { + int nmodboard; + u_int32_t val; + val=bus_r(FPGA_VERSION_REG)&0xff000000; + + // printf("version register %08x\n",val); + nmodboard=val >> 24; + #ifdef VERY_VERBOSE + printf("The board hosts %d modules\n",nmodboard); + #endif + nModBoard=nmodboard; + //getNModBoard()=nmodboard; + return nmodboard; +} + +int setNMod(int n) { + + // int fifo; + // int ifsta, ifsto, ifste; + int imod; + int rval; + int reg; + int nf=0; + int shiftfifo=SHIFTFIFO; + int ntot=getNModBoard(); + if (getProbes()==0) { + switch (dynamicRange) { + case 16: + shiftfifo=SHIFTFIFO-1; + break; + case 8: + shiftfifo=SHIFTFIFO-2; + break; + case 4: + shiftfifo=SHIFTFIFO-3; + break; + case 1: + shiftfifo=SHIFTFIFO-5; + break; + default: + shiftfifo=SHIFTFIFO; + } + } else + shiftfifo=SHIFTFIFO; + + +#ifdef VERBOSE + printf("SetNMod called arg %d -- dr %d shiftfifo %d\n",n,dynamicRange,shiftfifo); +#endif + if (n>=0 && n<=ntot) { + nModX=n; + + /*d isable the fifos relative to the unused modules */ + for (ififo=0; ififo>FIFO_NM_OFF, (reg&FIFO_NC_MASK)>>FIFO_NC_OFF, FIFO_COUNTR_REG_OFF+(ififo<>FIFO_NM_OFF, (reg&FIFO_NC_MASK)>>FIFO_NC_OFF, FIFO_COUNTR_REG_OFF+(ififo<> 32; + vMSB=v64&(0xffffffff); + bus_w(aMSB,vMSB); + } + return get64BitReg(aLSB, aMSB); + +} + +int64_t get64BitReg(int aLSB, int aMSB){ + int64_t v64; + u_int32_t vLSB,vMSB; + vMSB=bus_r(aMSB); + vLSB=bus_r(aLSB); + v64=vMSB; + v64=(v64<<32) | vLSB; +#ifdef VERBOSE + printf("MSB %08x LSB %08x, %016llx\n", vMSB, vLSB, v64); +#endif + + return v64; +} + +int64_t setFrames(int64_t value){ + return set64BitReg(value, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); +} + +int64_t getFrames(){ + return get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); +} + +int64_t setExposureTime(int64_t value){ + /* time is in ns */ + if (value!=-1) + value*=(1E-9*CLK_FREQ); + + if (masterMode==IS_SLAVE && syncMode==MASTER_GATES) + setGates(1); + + return set64BitReg(value,SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getExposureTime(){ + return get64BitReg(GET_EXPTIME_LSB_REG, GET_EXPTIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setGates(int64_t value){ + return set64BitReg(value, SET_GATES_LSB_REG, SET_GATES_MSB_REG); +} + +int64_t getGates(){ + return get64BitReg(GET_GATES_LSB_REG, GET_GATES_MSB_REG); +} + +int64_t setPeriod(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + + + + return set64BitReg(value,SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getPeriod(){ + return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setDelay(int64_t value){ + /* time is in ns */ + if (value!=-1) { + value*=(1E-9*CLK_FREQ); + } + return set64BitReg(value,SET_DELAY_LSB_REG, SET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getDelay(){ + return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t setTrains(int64_t value){ + return set64BitReg(value, SET_TRAINS_LSB_REG, SET_TRAINS_MSB_REG); +} + +int64_t getTrains(){ + return get64BitReg(GET_TRAINS_LSB_REG, GET_TRAINS_MSB_REG); +} + + +int64_t setProbes(int64_t value){ + int ow; + int nm=setNMod(-1); + switch (getDynamicRange()) { + case 32: + ow=1; + break; + case 16: + ow=2; + break; + case 8: + ow=3; + break; + case 4: + ow=4; + break; + case 1: + ow=5; + break; + default: + ow=1; + } + if (value>=0) { + setCSregister(ALLMOD); + initChipWithProbes(0, ow,value, ALLMOD); + putout("0000000000000000",ALLMOD); + setNMod(nm); + getDynamicRange(); // needed to change dataBytes + } + return getProbes(); +} + + +int64_t setProgress() { + + //????? eventually call after setting the registers + return 100; +} + + +int64_t getProgress() { + + + //should be done in firmware!!!! + return 0; + +} + + +int64_t getActualTime(){ + return get64BitReg(GET_ACTUAL_TIME_LSB_REG, GET_ACTUAL_TIME_MSB_REG)/(1E-9*CLK_FREQ); +} + +int64_t getMeasurementTime(){ + int64_t v=get64BitReg(GET_MEASUREMENT_TIME_LSB_REG, GET_MEASUREMENT_TIME_MSB_REG); + int64_t mask=0x8000000000000000; + + if (v & mask ) { +#ifdef VERBOSE + printf("no measurement time left\n"); +#endif + return -1E+9; + } else + return v/(1E-9*CLK_FREQ); +} + + + +int64_t getProbes(){ + u_int32_t shiftin=bus_r(GET_SHIFT_IN_REG); + u_int32_t np=(shiftin >>PROBES_OFF) & PROBES_MASK; +#ifdef VERYVERBOSE + printf("%08x ",shiftin); + printf("probes==%01x\n",np); +#endif + + return np; + +} + + +int setDACRegister(int idac, int val, int imod) { + u_int32_t addr, reg, mask; + int off; +#ifdef VERBOSE + printf("Settings dac %d module %d register to %d\n",idac,imod,val); +#endif + if ((idac%2)==0) { + addr=MOD_DACS1_REG; + } else { + addr=MOD_DACS2_REG; + } + off=(idac%3)*10; + mask=~((0x3ff)<=0 && val>off)&0x3ff; +#ifdef VERBOSE + printf("Dac %d module %d register is %d\n",idac,imod,val); +#endif + return val; +} + + + + +u_int32_t runBusy(void) { + return bus_r(STATUS_REG)&RUN_BUSY_BIT; +} + +u_int32_t dataPresent(void) { + return bus_r(LOOK_AT_ME_REG); +} + +u_int32_t runState(void) { + int s=bus_r(STATUS_REG); +#ifdef SHAREDMEMORY + if (s&RUN_BUSY_BIT) + write_status_sm("Running"); + else + write_status_sm("Stopped"); + + write_istatus_sm(s); + +#endif +#ifdef VERBOSE + printf("status %08x\n",s); +#endif + return s; +} + + +// State Machine + +u_int32_t startStateMachine(){ +#ifdef VERBOSE + printf("Starting State Machine\n"); +#endif + fifoReset(); + now_ptr=(char*)ram_values; +#ifdef SHAREDMEMORY + write_stop_sm(0); + write_status_sm("Started"); +#endif +#ifdef MCB_FUNCS + setCSregister(ALLMOD); + clearSSregister(ALLMOD); +#endif + putout("0000000000000000",ALLMOD); + bus_w(CONTROL_REG, START_ACQ_BIT | START_EXPOSURE_BIT); + return OK; +} + + + + +u_int32_t stopStateMachine(){ + +#ifdef VERBOSE + printf("Stopping State Machine\n"); +#endif +#ifdef SHAREDMEMORY + write_stop_sm(1); + write_status_sm("Stopped"); +#endif + bus_w(CONTROL_REG, STOP_ACQ_BIT); + usleep(500); + if (!runBusy()) + return OK; + else + return FAIL; +} + + +u_int32_t startReadOut(){ + u_int32_t status; +#ifdef VERBOSE + printf("Starting State Machine Readout\n"); +#endif + status=bus_r(STATUS_REG)&RUN_BUSY_BIT; +#ifdef DEBUG + printf("State machine status is %08x\n",bus_r(STATUS_REG)); +#endif + bus_w(CONTROL_REG, START_ACQ_BIT |START_READOUT_BIT); // start readout + return OK; +} + + +// fifo routines + +u_int32_t fifoReset(void) { +#ifdef DEBUG + printf("resetting fifo\n"); +#endif + bus_w(FIFO_CNTRL_REG_OFF+(ALLFIFO<128) + printf("chip %d ch %d %d\n",ichip/128, ichip%128, (fifoReadCounter(ichip/128)&FIFO_COUNTER_MASK)); +#endif + } + //#endif + */ + + + +#ifdef VERYVERBOSE + printf("Copying to ptr %x %d\n",now_ptr, dataBytes); + printf("after readout %08x %08x\n", runState(), bus_r(LOOK_AT_ME_REG)); + for (ichip=0; ichip0) { + now_ptr+=dataBytes; + } + return ram_values; +} + + + +u_int32_t* decode_data(int *datain) +{ + u_int32_t *dataout; + // const char one=1; + const int bytesize=8; + char *ptr=(char*)datain; + //int nbits=dynamicRange; + int ipos=0, ichan=0;; + //int nch, boff=0; + int ibyte;//, ibit; + char iptr; + +#ifdef VERBOSE + printf("Decoding data for DR %d\n",dynamicRange); +#endif + dataout=malloc(nChans*nChips*nModX*4); + ichan=0; + switch (dynamicRange) { + case 1: + for (ibyte=0; ibyte>(ipos))&0x1; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibyte>(ipos*4))&0xf; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichan0) { + nm=setNMod(-1); + if (dr==1) { + dynamicRange=1; + ow=5; + } else if (dr<=4) { + dynamicRange=4; + ow=4; + } else if (dr<=8) { + dynamicRange=8; + ow=3; + } else if (dr<=16) { + dynamicRange=16; + ow=2; + } else { + dynamicRange=32; + ow=0; //or 1? + } + setCSregister(ALLMOD); + initChipWithProbes(0, ow,np, ALLMOD); + putout("0000000000000000",ALLMOD); + setNMod(nm); + } + + + return getDynamicRange(); +} + + + + + + +int getDynamicRange() { + int dr; + u_int32_t shiftin=bus_r(GET_SHIFT_IN_REG); + u_int32_t outmux=(shiftin >> OUTMUX_OFF) & OUTMUX_MASK; + u_int32_t probes=(shiftin >> PROBES_OFF) & PROBES_MASK; +#ifdef VERYVERBOSE + printf("%08x ",shiftin); + printf("outmux=%02x probes=%d\n",outmux,probes); +#endif + + switch (outmux) { + case 2: + dr=16; + break; + case 4: + dr=8; + break; + case 8: + dr=4; + break; + case 16: + dr=1; + break; + default: + dr=32; + } + dynamicRange=dr; + if (probes==0) { + dataBytes=nModX*nModY*NCHIP*NCHAN*dynamicRange/8; + } else { + dataBytes=nModX*nModY*NCHIP*NCHAN*4;/// + } +#ifdef VERBOSE + printf("Number of data bytes %d - probes %d dr %d\n", dataBytes, probes, dr); +#endif + if (allocateRAM()==OK) { + ; + } else + printf("ram not allocated\n"); + + return dynamicRange; + +} + +int testBus() { + u_int32_t j; + u_int64_t i, n, nt; + //char cmd[100]; + u_int32_t val=0x0; + int ifail=OK; + // printf("%s\n",cmd); + // system(cmd); + i=0; + + n=1000000; + nt=n/100; + printf("testing bus %d times\n",n); + while (i0) + storeInRAM=1; + else + storeInRAM=0; + return allocateRAM(); +} + + +int allocateRAM() { + size_t size; + u_int32_t nt, nf; + nt=setTrains(-1); + nf=setFrames(-1); + if (nt==0) nt=1; + if (nf==0) nf=1; + // ret=clearRAM(); + if (storeInRAM) { + size=dataBytes*nf*nt; + if (size +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +int mapCSP0(void); +u_int32_t bus_w(u_int32_t offset, u_int32_t data); +u_int32_t bus_r(u_int32_t offset); + + +u_int32_t putout(char *s, int modnum); +u_int32_t readin(int modnum); +u_int32_t setClockDivider(int d); +u_int32_t getClockDivider(); +u_int32_t setSetLength(int d); +u_int32_t getSetLength(); +u_int32_t setWaitStates(int d); +u_int32_t getWaitStates(); +u_int32_t setTotClockDivider(int d); +u_int32_t getTotClockDivider(); +u_int32_t setTotDutyCycle(int d); +u_int32_t getTotDutyCycle(); + +u_int32_t setExtSignal(int d, enum externalSignalFlag mode); +int getExtSignal(int d); + +u_int32_t setFPGASignal(int d, enum externalSignalFlag mode); +int getFPGASignal(int d); + +int setTiming(int t); + + + + + + +int setConfigurationRegister(int d); +int setToT(int d); +int setContinousReadOut(int d); + +int setDACRegister(int idac, int val, int imod); + + +u_int64_t getMcsNumber(); +u_int32_t getMcsVersion(); +u_int32_t testFifos(void); +u_int32_t testFpga(void); +u_int32_t testRAM(void); +int testBus(void); +int64_t set64BitReg(int64_t value, int aLSB, int aMSB); +int64_t get64BitReg(int aLSB, int aMSB); + +int64_t setFrames(int64_t value); +int64_t getFrames(); + +int64_t setExposureTime(int64_t value); +int64_t getExposureTime(); + +int64_t setGates(int64_t value); +int64_t getGates(); + +int64_t setDelay(int64_t value); +int64_t getDelay(); + +int64_t setPeriod(int64_t value); +int64_t getPeriod(); + +int64_t setTrains(int64_t value); +int64_t getTrains(); + +int64_t setProbes(int64_t value); +int64_t getProbes(); + +int64_t getProgress(); +int64_t setProgress(); + +int64_t getActualTime(); +int64_t getMeasurementTime(); + +u_int32_t runBusy(void); +u_int32_t runState(void); +u_int32_t dataPresent(void); + + +u_int32_t startStateMachine(); +u_int32_t stopStateMachine(); +u_int32_t startReadOut(); +u_int32_t fifoReset(void); +u_int32_t fifoReadCounter(int fifonum); +u_int32_t fifoReadStatus(); + + +u_int32_t fifo_full(void); + + + +u_int32_t* fifo_read_event(); +u_int32_t* decode_data(int* datain); +//u_int32_t move_data(u_int64_t* datain, u_int64_t* dataout); +int setDynamicRange(int dr); +int getDynamicRange(); +int getNModBoard(); +int setNMod(int n); +int setStoreInRAM(int b); +int allocateRAM(); +int clearRAM(); + + +int setMaster(int f); +int setSynchronization(int s); + + +/* + +u_int32_t setNBits(u_int32_t); +u_int32_t getNBits(); +*/ + +/* +//move to mcb_funcs? + +int readOutChan(int *val); +u_int32_t getModuleNumber(int modnum); +int testShiftIn(int imod); +int testShiftOut(int imod); +int testShiftStSel(int imod); +int testDataInOut(int num, int imod); +int testExtPulse(int imod); +int testExtPulseMux(int imod, int ow); +int testDataInOutMux(int imod, int ow, int num); +int testOutMux(int imod); +int testFpgaMux(int imod); +int calibration_sensor(int num, int *values, int *dacs) ; +int calibration_chip(int num, int *values, int *dacs); +*/ + + +#endif diff --git a/slsDetectorSoftware/mythenDetectorServer/gitInfo.txt b/slsDetectorSoftware/mythenDetectorServer/gitInfo.txt new file mode 100644 index 000000000..fe9b46b0f --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/gitInfo.txt @@ -0,0 +1,9 @@ +Path: slsDetectorsPackage/slsDetectorSoftware/mythenDetectorServer +URL: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git/mythenDetectorServer +Repository Root: origin git@git.psi.ch:sls_detectors_software/sls_detector_software.git +Repsitory UUID: 8aceb5d4b0ca6bd95a11b53e7a799b463b92d51b +Revision: 106 +Branch: developer +Last Changed Author: Dhanya_Maliakal +Last Changed Rev: 334 +Last Changed Date: 2016-08-12 11:08:03 +0200 diff --git a/slsDetectorSoftware/mythenDetectorServer/gitInfoMythen.h b/slsDetectorSoftware/mythenDetectorServer/gitInfoMythen.h new file mode 100644 index 000000000..81d1316a9 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/gitInfoMythen.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "git@git.psi.ch:sls_detectors_software/sls_detector_software.git/mythenDetectorServer" +//#define SVNREPPATH "" +#define SVNREPUUID "8aceb5d4b0ca6bd95a11b53e7a799b463b92d51b" +//#define SVNREV 0x334 +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "Dhanya_Maliakal" +#define SVNREV 0x334 +#define SVNDATE 0x20160812 +// diff --git a/slsDetectorSoftware/mythenDetectorServer/gitInfoMythenTmp.h b/slsDetectorSoftware/mythenDetectorServer/gitInfoMythenTmp.h new file mode 100644 index 000000000..58e48f497 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/gitInfoMythenTmp.h @@ -0,0 +1,11 @@ +//#define SVNPATH "" +#define SVNURL "" +//#define SVNREPPATH "" +#define SVNREPUUID "" +//#define SVNREV "" +//#define SVNKIND "" +//#define SVNSCHED "" +#define SVNAUTH "" +#define SVNREV "" +#define SVNDATE "" +// diff --git a/slsDetectorSoftware/mythenDetectorServer/mcb_funcs.c b/slsDetectorSoftware/mythenDetectorServer/mcb_funcs.c new file mode 100755 index 000000000..5efb2ae4f --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/mcb_funcs.c @@ -0,0 +1,2710 @@ +#ifdef MCB_FUNCS + +#include +#include +#include +#include +#include +#include "registers.h" + +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" + +/* global variables */ +#undef DEBUG +#undef DEBUGOUT + +extern int nModX; +extern int nModBoard; +extern int dataBytes; +extern int dynamicRange; +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +const enum detectorType myDetectorType=MYTHEN; +enum detectorSettings thisSettings; + +int sChan, sChip, sMod, sDac, sAdc; +const int allSelected=-2; +const int noneSelected=-1; + + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +dacs_t *detectorDacs=NULL; +dacs_t *detectorAdcs=NULL; +//int numberOfProbes; + + + + + + + + +int initDetector() { + int imod; + // sls_detector_module *myModule; + int n=getNModBoard(); + nModX=n; + //#ifdef VERBOSE + printf("Board is for %d modules\n",n); + //#endif + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorChips=malloc(n*NCHIP*sizeof(int)); + + detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); + detectorDacs=malloc(n*NDAC*sizeof(dacs_t)); + detectorAdcs=malloc(n*NADC*sizeof(dacs_t)); +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",detectorModules, detectorModules+n); + printf("chips from 0x%x to 0x%x\n",detectorChips, detectorChips+n*NCHIP); + printf("chans from 0x%x to 0x%x\n",detectorChans, detectorChans+n*NCHIP*NCHAN); + printf("dacs from 0x%x to 0x%x\n",detectorDacs, detectorDacs+n*NDAC); + printf("adcs from 0x%x to 0x%x\n",detectorAdcs, detectorAdcs+n*NADC); +#endif + for (imod=0; imoddacs=detectorDacs+imod*NDAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*NADC; + (detectorModules+imod)->chipregs=detectorChips+imod*NCHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*NCHIP*NCHAN; + (detectorModules+imod)->ndac=NDAC; + (detectorModules+imod)->nadc=NADC; + (detectorModules+imod)->nchip=NCHIP; + (detectorModules+imod)->nchan=NCHIP*NCHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + setCSregister(ALLMOD); + setSSregister(ALLMOD); + counterClear(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + + /* initialize dynamic range etc. */ + dynamicRange=getDynamicRange(); + nModX=setNMod(-1); + + + + + + //dataBytes=nModX*NCHIP*NCHAN*4; + // dynamicRange=32; + // initChip(0, 0,ALLMOD); + //nModX=n; + // + // allocateRAM(); + + + + + return OK; +} + + + + +int copyChannel(sls_detector_channel *destChan, sls_detector_channel *srcChan) { + destChan->chan=srcChan->chan; + destChan->chip=srcChan->chip; + destChan->module=srcChan->module; + destChan->reg=srcChan->reg; + return OK; +} + + +int copyChip(sls_detector_chip *destChip, sls_detector_chip *srcChip) { + + int ichan; + int ret=OK; + if ((srcChip->nchan)>(destChip->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + + destChip->nchan=srcChip->nchan; + destChip->reg=srcChip->reg; + destChip->chip=srcChip->chip; + destChip->module=srcChip->module; + for (ichan=0; ichan<(srcChip->nchan); ichan++) { + *((destChip->chanregs)+ichan)=*((srcChip->chanregs)+ichan); + } + return ret; +} + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { + + int ichip, idac, ichan, iadc; + + int ret=OK; + +#ifdef VERBOSE + printf("Copying module %x to module %x\n",srcMod,destMod); +#endif + + if (srcMod->module>=0) { +#ifdef VERBOSE + printf("Copying module number %d to module number %d\n",srcMod->module,destMod->module); +#endif + destMod->module=srcMod->module; + } + if (srcMod->serialnumber>=0){ +/* #ifdef VERBOSE */ +/* printf("Copying module serial number %x to module serial number %x\n",srcMod->serialnumber,destMod->serialnumber); */ +/* #endif */ + destMod->serialnumber=srcMod->serialnumber; + } + if ((srcMod->nchip)>(destMod->nchip)) { + printf("Number of chip of source is larger than number of chips of destination\n"); + return FAIL; + } + if ((srcMod->nchan)>(destMod->nchan)) { + printf("Number of channels of source is larger than number of channels of destination\n"); + return FAIL; + } + if ((srcMod->ndac)>(destMod->ndac)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + if ((srcMod->nadc)>(destMod->nadc)) { + printf("Number of dacs of source is larger than number of dacs of destination\n"); + return FAIL; + } + +#ifdef VERBOSE + printf("DACs: src %d, dest %d\n",srcMod->ndac,destMod->ndac); + printf("ADCs: src %d, dest %d\n",srcMod->nadc,destMod->nadc); + printf("Chips: src %d, dest %d\n",srcMod->nchip,destMod->nchip); + printf("Chans: src %d, dest %d\n",srcMod->nchan,destMod->nchan); + +#endif + + + + destMod->ndac=srcMod->ndac; + destMod->nadc=srcMod->nadc; + destMod->nchip=srcMod->nchip; + destMod->nchan=srcMod->nchan; + if (srcMod->reg>=0) + destMod->reg=srcMod->reg; +#ifdef VERBOSE + printf("Copying register %x (%x)\n",destMod->reg,srcMod->reg ); +#endif + if (srcMod->gain>=0) + destMod->gain=srcMod->gain; + if (srcMod->offset>=0) + destMod->offset=srcMod->offset; + + // printf("copying gain and offset %f %f to %f %f\n",srcMod->gain,srcMod->offset,destMod->gain,destMod->offset); + + for (ichip=0; ichip<(srcMod->nchip); ichip++) { + if (*((srcMod->chipregs)+ichip)>=0) + *((destMod->chipregs)+ichip)=*((srcMod->chipregs)+ichip); + } + for (ichan=0; ichan<(srcMod->nchan); ichan++) { + if (*((srcMod->chanregs)+ichan)>=0) + *((destMod->chanregs)+ichan)=*((srcMod->chanregs)+ichan); + } + for (idac=0; idac<(srcMod->ndac); idac++) { + if (*((srcMod->dacs)+idac)>=0) + *((destMod->dacs)+idac)=*((srcMod->dacs)+idac); + } + for (iadc=0; iadc<(srcMod->nadc); iadc++) { + if (*((srcMod->adcs)+iadc)>=0) + *((destMod->adcs)+iadc)=*((srcMod->adcs)+iadc); + } + return ret; +} + + + +/* Register commands */ + + +int clearDACSregister(int imod) { + putout("0000000001000000",imod); + putout("0000000101000000",imod); + putout("0000000101000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Clearing DAC shiftregister\n"); +#endif + /* + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + */ + sDac=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + +int nextDAC(int imod) { + putout("0000000001000000",imod); + putout("0000000001001000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Next DAC\n"); +#endif + sDac++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return OK; +} + + +int clearCSregister(int imod) { + + putout("0000000001000000",imod); + putout("0000100001000000",imod); + putout("0000100001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Clearing CS shiftregister\n"); +#endif + /* + sChan=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + */ + sChip=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + //putout("0000000000000000",imod); + return 0; +} + +int setCSregister(int imod){ + + putout("0000000001000000",imod); + putout("0001000001000000",imod); + putout("0001000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Setting CS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChip=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextChip(int imod){ + + putout("0000000001000000",imod); + putout("0010000001000000",imod); + putout("0000000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "Next Chip\n"); +#endif + sChip++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int firstChip(int imod){ + + putout("0100000001000000",imod); + putout("0110000001000000",imod); + putout("0100000001000000",imod); +#ifdef DEBUG + fprintf(stdout, "First Chip\n"); +#endif + sChip=0; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int clearSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0000111000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Clearing SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=noneSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int setSSregister(int imod){ + int i; + putout("0000011000000000",imod); + for (i=0; i<10; i++) + putout("0001011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"Setting SS shiftregister\n"); +#endif + putout("0000000000000000",imod); + sChan=allSelected; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int nextStrip(int imod){ + putout("0000011000000000",imod); + putout("0010011000000000",imod); + putout("0000011000000000",imod); +#ifdef DEBUG + fprintf(stdout,"|-"); +#endif + sChan++; + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + return 0; +} + +int selChannel(const int strip,int imod) { + int istrip; + clearSSregister(imod); + nextStrip(imod); + for (istrip=0; istrip=0 && imoddacs[idac]=v; + detectorDacs[ireg+NDAC*imod]=v; + //#ifdef VERBOSE +#ifdef VERBOSE + printf("module=%d index=%d, val=%d addr=%x\n",imod, idac, v, detectorDacs+idac+NDAC*imod); +#endif + + setDACRegister(ireg,v,imod); + + /* + + reg=bus_r(MOD_DACS1_REG+(imod<dacs[idac]=v; + + + + reg=bus_r(MOD_DACS1_REG+(imod<=0) { + initDAC(cs, addr,val, imod); + /*#ifdef VERBOSE + iv=detectorDacs[ind+imod*NDAC]; + printf("module=%d index=%d, cs=%d, addr=%d, dacu=%d, set to %d",imod, ind,cs,addr,val,iv); +#endif + */ + //return val; + } + if (imod>=0 && imodgain,(detectorModules+imod)->offset); +#endif + if ((detectorModules+imod)->gain>0) + myg=(detectorModules+imod)->gain; + else { + if (thisSettings>=0 && thisSettings<3) + myg=g[thisSettings]; + // else + //myg=-1; + } + + if ((detectorModules+imod)->offset>0) + myo=(detectorModules+imod)->offset; + else { + if (thisSettings>=0 && thisSettings<3) + myo=o[thisSettings]; + // else + //myo=-1; + } + + if (myg>0 && myo>0) { + //ethr=(myo-detectorDacs[VTHRESH+imod*NDAC])*1000/myg; + + ethr=(myo-setDACRegister(VTHRESH,-1,imod))*1000/myg; + // else + // ethr=-1; + + } +#ifdef VERBOSE +#ifdef DACS_INT + printf("module=%d gain=%f, offset=%f, dacu=%d\n",imod, myg, myo,setDACRegister(VTHRESH,-1,imod)); +#else + printf("module=%d gain=%f, offset=%f, dacu=%f\n",imod, myg, myo,setDACRegister(VTHRESH,-1,imod)); +#endif + printf("Threshold energy of module %d is %d eV\n", imod, ethr); +#endif + + if (imod==0) + ret=ethr; + else { + if (ethr>(ret+100) || ethr<(ret-100)) + return FAIL; + } + } + } + return ret; +} + +int setThresholdEnergy(int ethr) { + float g[3]=DEFAULTGAIN; + float o[3]=DEFAULTOFFSET; + float myg=-1, myo=-1; + int dacu; + int imod; + int ret=ethr; + + setSettings(GET_SETTINGS); + if (thisSettings>=0 || thisSettings<3){ + myg=g[thisSettings]; + myo=o[thisSettings]; + } + for (imod=0; imodgain>0) + myg=(detectorModules+imod)->gain; + else + if (thisSettings>=0 && thisSettings<3) + myg=g[thisSettings]; + else + myg=-1; + if ((detectorModules+imod)->offset>0) + myo=(detectorModules+imod)->offset; + else + if (thisSettings>=0 && thisSettings<3) + myo=o[thisSettings]; + else + myo=-1; + } else { + if (thisSettings>=0 && thisSettings<3) + myo=o[thisSettings]; + else + myo=-1; + if (thisSettings>=0 && thisSettings<3) + myg=g[thisSettings]; + else + myg=-1; + } + if (myg>0 && myo>0) { + dacu=myo-myg*((float)ethr)/1000.; +#ifdef VERBOSE + printf("module %d (%x): gain %f, off %f, energy %d eV, dac %d\n",imod,(detectorModules+imod),(detectorModules+imod)->gain,(detectorModules+imod)->offset, ethr,dacu); +#endif + } else { + dacu=ethr; +#ifdef VERBOSE + printf("could not set threshold energy for module %d, settings %d (offset is %f; gain is %f)\n",imod,thisSettings,myo,myg); +#endif + } + initDACbyIndexDACU(VTHRESH, dacu, imod); + } + return ret; +} + + + +dacs_t getDACbyIndexDACU(int ind, int imod) { + /* + if (detectorDacs) { + if (imodndac) + return (detectorDacs[ind+imod*NDAC]); + } + return FAIL; + */ + return setDACRegister(ind, -1, imod); +} + + + +int initDAC(int dac_cs, int dac_addr, int value, int imod) { + int i; +#ifdef VERBOSE + printf("Programming dac %d %d with value %d\n", dac_cs, dac_addr, value); +#endif + clearDACSregister(imod); + /*if (dac_cs>0) {*/ + for (i=0; i0) {*/ + for (i=0; i=0) { +#ifdef VERBOSE + fprintf(stdout, "voltage %d\n", *(v+i)); +#endif + program_one_dac(iaddr, *(v+i),imod); + } + nextDAC(imod); + } + } + clearDACSregister(imod); + for (ichip=0; ichip<3; ichip++) { + set_one_dac(imod); + nextDAC(imod); + } + + return 0; +} + + + + +int setSettings(int i) { + int imod, isett, is; + int rgpr[]=RGPRVALS; + int rgsh1[]=RGSH1VALS; + int rgsh2[]=RGSH2VALS; + int irgpr, irgsh1, irgsh2; + + int v[NDAC]; + int ind; + for (ind=0; ind>(NTRIMBITS))&1; + int ae=(reg>>(NTRIMBITS+1))&1; + int coe=(reg>>(NTRIMBITS+2))&1; + int ocoe=(reg>>(NTRIMBITS+3))&1; + int counts=(reg>>(NTRIMBITS+4)); +#ifdef VERBOSE + printf("Initializing channel %d chip %d module %d reg %x\n",myChan.chan,myChan.chip,myChan.module, reg); + printf("trim %d, cae %d, ae %d, coe %d, ocoe %d, counts %d\n",ft, cae, ae, coe, ocoe, counts); +#endif + + if (myChan.chip<0) + setCSregister(myChan.module); + else + selChip(myChan.chip,myChan.module); + + if (myChan.chan<0) + setSSregister(myChan.module); + else + selChannel(myChan.chan,myChan.module); + + initChannel(ft,cae,ae, coe, ocoe, counts,myChan.module); + + setDynamicRange(dynamicRange); + + setCSregister(ALLMOD); + clearSSregister(ALLMOD); + putout("0000000000000000",ALLMOD); + + return myChan.reg; + +} + +int getChannelbyNumber(sls_detector_channel* myChan) { + int imod, ichip, ichan; + imod=myChan->module; + ichip=myChan->chip; + ichan=myChan->chan; + + if (detectorChans) { + if (imod=0) { + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + myChan->reg=detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan]; + return OK; + } + } + return FAIL; + +} + +int getTrimbit(int imod, int ichip, int ichan) { + if (detectorChans) { + if (imod=0) + if (ichip<(detectorModules+imod)->nchip && ichan<(detectorModules+imod)->nchan/(detectorModules+imod)->nchip) + return (detectorChans[imod*NCHAN*NCHIP+ichip*NCHAN+ichan] & TRIM_DR); + } //else + return -1; + + +} + +int initChannel(int ft,int cae, int ae, int coe, int ocoe, int counts, int imod){ + + int ibit, bit, i, im, ichip, ichan; + int chanmi, chanma, chipmi, chipma, modmi, modma; + + + + sMod=imod; + // printf("initializing module %d\n",sMod); + if (imod==ALLMOD) { + sMod=allSelected; + + // printf("initializing all modules\n"); + } + + if (sChan==allSelected) { + // printf("initializing all channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=NCHAN; + } else if (sChan==noneSelected || sChan>NCHAN || sChan<0) { + // printf("initializing no channels ft=%d coe=%d\n",ft,coe); + chanmi=0; + chanma=-1; + } else { + // printf("initializing channel %d ft=%d coe=%d\n",sChan, ft,coe); + chanmi=sChan; + chanma=sChan+1; + } + + if (sChip==allSelected) { + // printf("initializing all chips\n"); + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + // printf("initializing no chips\n"); + chipmi=0; + chipma=-1; + } else { + // printf("initializing chip %d\n",sChip); + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + return 1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChans) { + for (im=modmi; im63 || ft<0) { + fprintf(stdout,"Fine Threshold is %d while should be between 0 and 63!",ft); + return 1; + } + /*cal_enable*/ + if (cae) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + } + /*n_an_enable*/ + if (ae) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } else { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } + /*trb5*/ + ibit=5; + bit=ft & (1<>1; + int nchan, ichan; + int ft, cae, ae, coe, ocoe, counts, chanreg; + + + + nchan=myChip.nchan; + if (ichip<0) + setCSregister(imod); + else + selChip(ichip,imod); + + clearSSregister(imod); + for (ichan=0; ichan>(NTRIMBITS+1))&1; + ae=(chanreg>>(NTRIMBITS+2))&1; + coe=((chanreg)>>(NTRIMBITS+3))&1; + ocoe=((chanreg)>>(NTRIMBITS+4))&1; + counts=((chanreg)>>(NTRIMBITS+5)); + nextStrip(imod); + initChannel(ft,cae,ae, coe, ocoe, counts,imod); + } + initChip(obe,ow,imod); + return myChip.reg; + +} + +int getChipbyNumber(sls_detector_chip* myChip){ + int imod, ichip; + imod=myChip->module; + ichip=myChip->chip; + + if (detectorChips) { + if (imodnchip) { + myChip->reg=detectorChips[ichip+imod*NCHIP]; + myChip->nchan=NCHAN; + myChip->chanregs=detectorChans+imod*NCHAN*NCHIP+ichip*NCHIP; + return OK; + } + } + return FAIL; + +} + + + +int initChip(int obe, int ow,int imod){ + int i; + int im, ichip; + int chipmi, chipma, modmi, modma; + /* switch (ow) { + case 0:; + case 1: + setDynamicRange(32); + break; + case 2: + setDynamicRange(16); + break; + case 3: + setDynamicRange(8); + break; + case 4: + setDynamicRange(4); + break; + case 5: + setDynamicRange(1); + break; + default: + setDynamicRange(32); + break; + } + */ + +#ifdef DEBUGOUT + printf("Initializing chip\n"); +#endif + putout("0000000000000000",imod); +#ifdef DEBUGOUT + printf("Output mode= %d\n", ow); +#endif + + /* clearing shift in register */ + for (i=0; i<10; i++) + putout("0000100000000000",imod); + putout("0000000000000000",imod); + + if (ow>0) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + for (i=0; i<(OUTMUX_OFFSET-1); i++) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>1) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>2) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>3) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + if (ow>4) { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + } +#ifdef DEBUGOUT + printf("Output buffer enable= %d\n", obe); +#endif + if (obe) { + putout("0100000000000000",imod); + putout("0110000000000000",imod); + putout("0100000000000000",imod); + } else { + putout("0000000000000000",imod); + putout("0010000000000000",imod); + putout("0000000000000000",imod); + } + /*}*/ + putout("0000000000000000",imod); + + + + + + sMod=imod; + if (imod==ALLMOD) + sMod=allSelected; + + + if (sChip==allSelected) { + chipmi=0; + chipma=NCHIP; + } else if (sChip==noneSelected || sChip>NCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imNCHIP || sChip<0) { + chipmi=0; + chipma=-1; + } else { + chipmi=sChip; + chipma=sChip+1; + } + + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorChips) { + for (im=modmi; imnModX || sMod<0) {//(sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + if (detectorModules) { + for (im=modmi; imreg)=cm; +#ifdef VERBOSE + printf("imod=%d reg=%d (%x)\n",im,(detectorModules+im)->reg,(detectorModules+im)); +#endif + } + } + return 0; +} + +int initModulebyNumber(sls_detector_module myMod) { + + + int ichip, nchip, ichan, nchan; + int im, modmi,modma; + int ft, cae, ae, coe, ocoe, counts, chanreg; + int imod; + int obe; + int ow; + int v[NDAC]; + + + nchip=myMod.nchip; + nchan=(myMod.nchan)/nchip; + + imod=myMod.module; + sMod=imod; + + if (sMod==ALLMOD) + sMod=allSelected; + + if (sMod==allSelected) { + modmi=0; + modma=nModX;//getNModBoard(); + } else if (sMod==noneSelected || sMod>nModX || sMod<0) {// (sMod==noneSelected || sMod>getNModBoard() || sMod<0) { + modmi=0; + modma=-1; + } else { + modmi=sMod; + modma=sMod+1; + } + + + /* + for (idac=0; idac>(NTRIMBITS+1))&1; + ae=(chanreg>>(NTRIMBITS+2))&1; + coe=((chanreg)>>(NTRIMBITS+3))&1; + ocoe=((chanreg)>>(NTRIMBITS+4))&1; + counts=((chanreg)>>(NTRIMBITS+5)); + nextStrip(imod); + initChannel(ft,cae,ae, coe, ocoe, counts,imod); + } + obe=((myMod.chipregs)[ichip])&1; + ow=1;//((myMod.chipregs)[ichip])>>1; + initChip(obe,ow,imod); + nextChip(imod); + } + + + initMCBregisters(myMod.reg,imod); + + if (detectorModules) { + for (im=modmi; immodule; +#ifdef VERBOSE + printf("Getting module %d\n",imod); +#endif + if (detectorModules) { + copyModule(myMod,detectorModules+imod); + ; + } else + return FAIL; + + return OK; +} + +/* To chips */ +int clearCounter(int imod){ + int i; +#ifdef DEBUG + printf("Clearing counter with contclear\n"); +#endif + putout("0000000000000000",imod); + for (i=0; i<10; i++) + putout("0000000000010000",imod); + putout("0000000000000000",imod); + + return 0; +} + +int clearOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Clearing output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0000110000000000",imod); + putout("0000010000000000",imod); + return 0; +} +int setOutReg(int imod){ + int i; +#ifdef DEBUG + printf("Setting output register\n"); +#endif + putout("0000010000000000",imod); + for (i=0; i<10; i++) + putout("0001010000000000",imod); + putout("0000010000000000",imod); + return 0; +} + + +int extPulse(int ncal, int imod) { + int ical; +#ifdef DEBUG + printf("Giving a clock pulse to the counter\n"); +#endif + for (ical=0; ical0 && i%2==0) { + printf("Shift in: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<0 && (dum & (1<0) { + printf("Shift out: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, (dum &1<0 && i%2==0) { + printf("Shift stsel: module %d chip %i bit %d read %d instead of %d \n",k,j,i,val & 1<< j, i%2); + result++; + } + if (i%2>0 && (val & 1<> 1; + + + putout("0000000000000000",imod); + putout("0010000000000000",imod); //change mux setting + putout("0000000000000000",imod); + } + + printf("Test FpgaMux module %d : %d errors\n", imod,result); + if (result) + return 1; + else + return 0; +} + + + + + + + + + +int calibration_sensor(int num, int *v, int *dacs) { + int ich, ichip, imod; + int val[10]; + + + printf("calibrating sensor..."); + for (imod=0; imod + + +// Hardware definitions + +#define NCHAN 128 +#define NCHIP 12 //10 modified for PICASSO +#define NMAXMODX 24 +#define NMAXMODY 1 +#define NMAXMOD NMAXMODX*NMAXMODY +#define NDAC 6 +#define NADC 0 + +#define NCHANS NCHAN*NCHIP*NMAXMOD +#define NDACS NDAC*NMAXMOD + +#define NTRIMBITS 6 +#define NCOUNTBITS 24 + +//#define TRIM_DR ((2**NTRIMBITS)-1) +//#define COUNT_DR ((2**NCOUNTBITS)-1) +#define TRIM_DR (((int)pow(2,NTRIMBITS))-1) +#define COUNT_DR (((int)pow(2,NCOUNTBITS))-1) + + +#define ALLMOD 0xffff +#define ALLFIFO 0xffff + +#ifdef VIRTUAL +#define DEBUGOUT +#endif + +#define CLK_FREQ 100E+6 + + +#define THIS_SOFTWARE_VERSION 0x20090205 +#endif diff --git a/slsDetectorSoftware/mythenDetectorServer/registers.h b/slsDetectorSoftware/mythenDetectorServer/registers.h new file mode 100755 index 000000000..32f479c3a --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/registers.h @@ -0,0 +1,184 @@ +#ifndef REGISTERS_H +#define REGISTERS_H + + + +/* Definitions for FPGA*/ +#define CSP0 0x90000000 // Base Addresse CSP0 +#define CSP4 0xa0000000 // Base Addresse CSP4 + +//#define MEM_SIZE 0xFFFFFF // map so much memory +#define MEM_SIZE 0xFFFFFFF // map so much memory + + + +/* registers defined in FPGA */ +#define FIX_PATT_REG 0x000000 +#define FPGA_VERSION_REG 0x001000 +#define DUMMY_REG 0x002000 +#define CONTROL_REG 0x003000 +#define STATUS_REG 0x004000 +#define CONFIG_REG 0x005000 +#define SPEED_REG 0x006000 +#define EXT_SIGNAL_REG 0x007000 +#define SET_NBITS_REG 0x008000 +#define LOOK_AT_ME_REG 0x009000 + +#define SET_FRAMES_LSB_REG 0x00A000 +#define SET_FRAMES_MSB_REG 0x00B000 +#define GET_FRAMES_LSB_REG 0x00C000 +#define GET_FRAMES_MSB_REG 0x00D000 + +#define SET_EXPTIME_LSB_REG 0x00E000 +#define SET_EXPTIME_MSB_REG 0x00F000 +#define GET_EXPTIME_LSB_REG 0x010000 +#define GET_EXPTIME_MSB_REG 0x011000 + +#define SET_GATES_LSB_REG 0x012000 +#define SET_GATES_MSB_REG 0x013000 +#define GET_GATES_LSB_REG 0x014000 +#define GET_GATES_MSB_REG 0x015000 + +#define SET_PERIOD_LSB_REG 0x016000 +#define SET_PERIOD_MSB_REG 0x017000 +#define GET_PERIOD_LSB_REG 0x018000 +#define GET_PERIOD_MSB_REG 0x019000 + +#define SET_DELAY_LSB_REG 0x01A000 +#define SET_DELAY_MSB_REG 0x01B000 +#define GET_DELAY_LSB_REG 0x01C000 +#define GET_DELAY_MSB_REG 0x01D000 + +#define SET_TRAINS_LSB_REG 0x01E000 +#define SET_TRAINS_MSB_REG 0x01F000 +#define GET_TRAINS_LSB_REG 0x020000 +#define GET_TRAINS_MSB_REG 0x021000 + + +#define GET_SHIFT_IN_REG 0x022000 + +#define GET_MEASUREMENT_TIME_LSB_REG 0x023000 +#define GET_MEASUREMENT_TIME_MSB_REG 0x024000 + +#define GET_ACTUAL_TIME_LSB_REG 0x025000 +#define GET_ACTUAL_TIME_MSB_REG 0x026000 + +#define MOD_DACS1_REG 0x030000 +#define MOD_DACS2_REG 0x040000 + +#define MCB_CNTRL_REG_OFF 0x100000 +#define MCB_DOUT_REG_OFF 0x200000 +#define FIFO_CNTRL_REG_OFF 0x300000 +#define FIFO_COUNTR_REG_OFF 0x400000 +#define FIFO_DATA_REG_OFF 0x800000 + +#define SHIFTMOD 2 +#define SHIFTFIFO 9 + + + +/* values defined for FPGA */ +#define MCSNUM 0x0 +#define MCSVERSION 0x101 +#define FIXED_PATT_VAL 0xacdc1980 +#define FPGA_VERSION_VAL 0x00090514 +#define FPGA_INIT_PAT 0x60008 +#define FPGA_INIT_ADDR 0xb0000000 + +/* for control register */ +#define START_ACQ_BIT 0x00000001 +#define STOP_ACQ_BIT 0x00000002 +#define START_FIFOTEST_BIT 0x00000004 // ????? +#define STOP_FIFOTEST_BIT 0x00000008 // ?????? +#define START_READOUT_BIT 0x00000010 +#define STOP_READOUT_BIT 0x00000020 +#define START_EXPOSURE_BIT 0x00000040 +#define STOP_EXPOSURE_BIT 0x00000080 +#define START_TRAIN_BIT 0x00000100 +#define STOP_TRAIN_BIT 0x00000200 +#define SYNC_RESET 0x80000000 + +/* for status register */ +#define RUN_BUSY_BIT 0x00000001 +#define READOUT_BUSY_BIT 0x00000002 +#define FIFOTEST_BUSY_BIT 0x00000004 //???? +#define WAITING_FOR_TRIGGER_BIT 0x00000008 +#define DELAYBEFORE_BIT 0x00000010 +#define DELAYAFTER_BIT 0x00000020 +#define EXPOSING_BIT 0x00000040 +#define COUNT_ENABLE_BIT 0x00000080 +#define SOME_FIFO_FULL_BIT 0x00008000 // error! +#define ALL_FIFO_EMPTY_BIT 0x00010000 // data ready + +/* for fifo status register */ +#define FIFO_ENABLED_BIT 0x80000000 +#define FIFO_DISABLED_BIT 0x01000000 +#define FIFO_ERROR_BIT 0x08000000 +#define FIFO_EMPTY_BIT 0x04000000 +#define FIFO_DATA_READY_BIT 0x02000000 +#define FIFO_COUNTER_MASK 0x000001ff +#define FIFO_NM_MASK 0x00e00000 +#define FIFO_NM_OFF 21 +#define FIFO_NC_MASK 0x001ffe00 +#define FIFO_NC_OFF 9 + +/* for config register */ + +#define TOT_ENABLE_BIT 0x00000002 +#define TIMED_GATE_BIT 0x00000004 +#define CONT_RO_ENABLE_BIT 0x00080000 + + + +/* for speed register */ + +#define CLK_DIVIDER_MASK 0x000000ff +#define CLK_DIVIDER_OFFSET 0 +#define SET_LENGTH_MASK 0x00000f00 +#define SET_LENGTH_OFFSET 8 +#define WAIT_STATES_MASK 0x0000f000 +#define WAIT_STATES_OFFSET 12 +#define TOTCLK_DIVIDER_MASK 0xff000000 +#define TOTCLK_DIVIDER_OFFSET 24 +#define TOTCLK_DUTYCYCLE_MASK 0x00ff0000 +#define TOTCLK_DUTYCYCLE_OFFSET 16 + +/* for external signal register */ + +#define SIGNAL_OFFSET 4 +#define SIGNAL_MASK 0xF +#define EXT_SIG_OFF 0x0 +#define EXT_GATE_IN_ACTIVEHIGH 0x1 +#define EXT_GATE_IN_ACTIVELOW 0x2 +#define EXT_TRIG_IN_RISING 0x3 +#define EXT_TRIG_IN_FALLING 0x4 +#define EXT_RO_TRIG_IN_RISING 0x5 +#define EXT_RO_TRIG_IN_FALLING 0x6 +#define EXT_GATE_OUT_ACTIVEHIGH 0x7 +#define EXT_GATE_OUT_ACTIVELOW 0x8 +#define EXT_TRIG_OUT_RISING 0x9 +#define EXT_TRIG_OUT_FALLING 0xA +#define EXT_RO_TRIG_OUT_RISING 0xB +#define EXT_RO_TRIG_OUT_FALLING 0xC +#define EXT_OUT_LOW 0xD // to be implemented in firmware (and corrected in software) +#define EXT_OUT_HIGH 0xE // to be implemented in firmware (and corrected in software) +#define EXT_MASTER_SLAVE_SYNC 0xF // to be implemented in firmware (and corrected in software) + + + +/* fifo control register */ +#define FIFO_RESET_BIT 0x00000001 +#define FIFO_DISABLE_TOGGLE_BIT 0x00000002 + + +//chip shiftin register meaning + +#define OUTMUX_OFF 20 +#define OUTMUX_MASK 0x1f +#define PROBES_OFF 4 +#define PROBES_MASK 0x7f +#define OUTBUF_OFF 0 +#define OUTBUF_MASK 1 + + +#endif diff --git a/slsDetectorSoftware/mythenDetectorServer/server.c b/slsDetectorSoftware/mythenDetectorServer/server.c new file mode 100755 index 000000000..f39b221f5 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/server.c @@ -0,0 +1,91 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ +#include "communication_funcs.h" +#include "server_funcs.h" +#include + + +extern int sockfd; + + +void error(char *msg) +{ + perror(msg); +} + +int main(int argc, char *argv[]) +{ + int portno, b; + char cmd[100]; + int retval=OK; + int sd, fd; + + + if (argc==1) { + portno = DEFAULT_PORTNO; + sprintf(cmd,"%s %d &",argv[0],DEFAULT_PORTNO+1); + printf("opening control server on port %d\n",portno ); + system(cmd); + b=1; + } else { + portno = DEFAULT_PORTNO+1; + if ( sscanf(argv[1],"%d",&portno) ==0) { + printf("could not open stop server: unknown port\n"); + return 1; + } + b=0; + printf("opening stop server on port %d\n",portno); + } + + + + init_detector(b); //defined in server_funcs + + + sd=bindSocket(portno); //defined in communication_funcs + + sockfd=sd; + + + if (getServerError(sd)) { //defined in communication_funcs + printf("server error!\n"); + return -1; + } + + /* assign function table */ + function_table(); //defined in server_funcs +#ifdef VERBOSE + printf("function table assigned \n"); +#endif + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Waiting for client call\n"); +#endif + fd=acceptConnection(sockfd); //defined in communication_funcs +#ifdef VERY_VERBOSE + printf("Conenction accepted\n"); +#endif + if (fd>0) { + retval=decode_function(fd); //defined in server_funcs +#ifdef VERY_VERBOSE + printf("function executed\n"); +#endif + closeConnection(fd); //defined in communication_funcs +#ifdef VERY_VERBOSE + printf("connection closed\n"); +#endif + } + } + + exitServer(sockfd); //defined in communication_funcs + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/mythenDetectorServer/server_defs.h b/slsDetectorSoftware/mythenDetectorServer/server_defs.h new file mode 100755 index 000000000..e91bb5685 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/server_defs.h @@ -0,0 +1,43 @@ +#ifndef SERVER_DEFS_H +#define SERVER_DEFS_H + +#include "sls_detector_defs.h" + +#include + + +// Hardware definitions + +#define NCHAN 128 +#define NCHIP 10 +#define NMAXMODX 24 +#define NMAXMODY 1 +#define NMAXMOD NMAXMODX*NMAXMODY +#define NDAC 6 +#define NADC 0 + +#define NCHANS NCHAN*NCHIP*NMAXMOD +#define NDACS NDAC*NMAXMOD + +#define NTRIMBITS 6 +#define NCOUNTBITS 24 + +//#define TRIM_DR ((2**NTRIMBITS)-1) +//#define COUNT_DR ((2**NCOUNTBITS)-1) +#define TRIM_DR (((int)pow(2,NTRIMBITS))-1) +#define COUNT_DR (((int)pow(2,NCOUNTBITS))-1) + + +#define ALLMOD 0xffff +#define ALLFIFO 0xffff + +#ifdef VIRTUAL +#define DEBUGOUT +#endif + +#define CLK_FREQ 100E+6 + + +#define THIS_SOFTWARE_VERSION 0x20120419 +#define THIS_REVISION "$Rev: 379 $" +#endif diff --git a/slsDetectorSoftware/mythenDetectorServer/server_funcs.c b/slsDetectorSoftware/mythenDetectorServer/server_funcs.c new file mode 100755 index 000000000..7bae5b76b --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/server_funcs.c @@ -0,0 +1,2851 @@ +#include "sls_detector_defs.h" +#include "server_funcs.h" +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "firmware_funcs.h" +#include "mcb_funcs.h" +#include "trimming_funcs.h" +#include "gitInfoMythen.h" + +// Global variables + +int (*flist[256])(int); + + + +#ifdef MCB_FUNCS +extern const enum detectorType myDetectorType; +#endif +#ifndef MCB_FUNCS +const enum detectorType myDetectorType=MYTHEN; +#endif +extern int nModX; +extern int nModY; +extern int dataBytes; +extern int dynamicRange; +extern int storeInRAM; + +extern int lockStatus; +extern char lastClientIP[INET_ADDRSTRLEN]; +extern char thisClientIP[INET_ADDRSTRLEN]; +extern int differentClients; + +/* global variables for optimized readout */ +extern int *ram_values; +char *dataretval=NULL; +int nframes, iframes, dataret; +char mess[MAX_STR_LENGTH]; + + + + + +int init_detector( int b) { +#ifndef PICASSOD + printf("This is a MYTHEN detector with %d chips per module\n", NCHIP); +#else + printf("This is a PICASSO detector with %d chips per module\n", NCHIP); +#endif + mapCSP0(); +#ifndef VIRTUAL + system("bus -a 0xb0000000 -w 0xd0008"); +#ifdef VERBOSE + printf("setting wait states \n"); + system("bus -a 0xb0000000"); +#endif +#endif + testFpga(); + if (b) { +#ifdef MCB_FUNCS + initDetector(); + setSettings(GET_SETTINGS); + testRAM(); +#endif + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + setMaster(GET_MASTER); + setSynchronization(GET_SYNCHRONIZATION_MODE); + } + strcpy(mess,"dummy message"); + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + lockStatus=0; + return OK; +} + + +int decode_function(int file_des) { + int fnum,n; + int retval=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveDataOnly(file_des,&fnum,sizeof(fnum)); + if (n <= 0) { + printf("ERROR reading from socket %d, %d %d\n", n, fnum, file_des); + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif + +#ifdef VERBOSE + printf( "calling function fnum = %d %x\n",fnum,flist[fnum]); +#endif + if (fnum<0 || fnum>255) + fnum=255; + retval=(*flist[fnum])(file_des); + if (retval==FAIL) + printf( "Error executing the function = %d \n",fnum); + return retval; +} + + +int function_table() { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_EXEC_COMMAND]=&exec_command; + flist[F_GET_DETECTOR_TYPE]=&get_detector_type; + flist[F_SET_NUMBER_OF_MODULES]=&set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES]=&get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG]=&set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE]=&set_external_communication_mode; + flist[F_GET_ID]=&get_id; + flist[F_DIGITAL_TEST]=&digital_test; + flist[F_WRITE_REGISTER]=&write_register; + flist[F_READ_REGISTER]=&read_register; + flist[F_SET_DAC]=&set_dac; + flist[F_GET_ADC]=&get_adc; + flist[F_SET_CHANNEL]=&set_channel; + flist[F_SET_CHIP]=&set_chip; + flist[F_SET_MODULE]=&set_module; + flist[F_GET_CHANNEL]=&get_channel; + flist[F_GET_CHIP]=&get_chip; + flist[F_GET_MODULE]=&get_module; + flist[F_GET_THRESHOLD_ENERGY]=&get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY]=&set_threshold_energy; + flist[F_SET_SETTINGS]=&set_settings; + flist[F_START_ACQUISITION]=&start_acquisition; + flist[F_STOP_ACQUISITION]=&stop_acquisition; + flist[F_START_READOUT]=&start_readout; + flist[F_GET_RUN_STATUS]=&get_run_status; + flist[F_READ_FRAME]=&read_frame; + flist[F_READ_ALL]=&read_all; + flist[F_START_AND_READ_ALL]=&start_and_read_all; + flist[F_SET_TIMER]=&set_timer; + flist[F_GET_TIME_LEFT]=&get_time_left; + flist[F_SET_DYNAMIC_RANGE]=&set_dynamic_range; + flist[F_SET_ROI]=&set_roi; + flist[F_SET_SPEED]=&set_speed; + flist[F_SET_READOUT_FLAGS]=&set_readout_flags; + flist[F_EXECUTE_TRIMMING]=&execute_trimming; + flist[F_LOCK_SERVER]=&lock_server; + flist[F_SET_PORT]=&set_port; + flist[F_GET_LAST_CLIENT_IP]=&get_last_client_ip; + flist[F_UPDATE_CLIENT]=&update_client; + flist[F_SET_MASTER]=&set_master; + flist[F_SET_SYNCHRONIZATION_MODE]=&set_synchronization; +#ifdef VERBOSE + /* for (i=0;i<256;i++){ + printf("function %d located at %x\n",i,flist[i]); + }*/ +#endif + return OK; +} + + +int M_nofunc(int file_des){ + + int retval=FAIL; + sprintf(mess,"Unrecognized Function\n"); + printf(mess); + sendDataOnly(file_des,&retval,sizeof(retval)); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + + +int exit_server(int file_des) { + int retval=FAIL; + sendDataOnly(file_des,&retval,sizeof(retval)); + printf("closing server."); + sprintf(mess,"closing server"); + sendDataOnly(file_des,mess,sizeof(mess)); + return GOODBYE; +} + +int exec_command(int file_des) { + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int retval=OK; + int sysret=0; + int n=0; + + /* receive arguments */ + n = receiveDataOnly(file_des,cmd,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (retval==OK) { +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + if (lockStatus==0 || differentClients==0) + sysret=system(cmd); + + //should be replaced by popen + if (sysret==0) { + sprintf(answer,"Succeeded\n"); + if (lockStatus==1 && differentClients==1) + sprintf(answer,"Detector locked by %s\n", lastClientIP); + } else { + sprintf(answer,"Failed\n"); + retval=FAIL; + } + } else { + sprintf(answer,"Could not receive the command\n"); + } + + /* send answer */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + n = sendDataOnly(file_des,answer,MAX_STR_LENGTH); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + retval=FAIL; + } + + + /*return ok/fail*/ + return retval; + +} + + + +int get_detector_type(int file_des) { + int n=0; + enum detectorType ret; + int retval=OK; + + sprintf(mess,"Can't return detector type\n"); + + + /* receive arguments */ + /* execute action */ + ret=myDetectorType; + +#ifdef VERBOSE + printf("Returning detector type %d\n",ret); +#endif + + /* send answer */ + /* send OK/failed */ + if (differentClients==1) + retval=FORCE_UPDATE; + + n += sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + + +} + + +int set_number_of_modules(int file_des) { + int n; + int arg[2], ret=0; + int retval=OK; + int dim, nm; + + sprintf(mess,"Can't set number of modules\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket %d", n); + retval=GOODBYE; + } + if (retval==OK) { + dim=arg[0]; + nm=arg[1]; + + /* execute action */ +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + + //if (nm!=GET_FLAG) { + if (dim!=X && nm!=GET_FLAG) { + retval=FAIL; + sprintf(mess,"Can't change module number in dimension %d\n",dim); + } else { + if (lockStatus==1 && differentClients==1 && nm!=GET_FLAG) { + sprintf(mess,"Detector locked by %s\n", lastClientIP); + retval=FAIL; + } else { + ret=setNMod(nm); + if (nModX==nm || nm==GET_FLAG) { + retval=OK; + if (differentClients==1) + retval=FORCE_UPDATE; + } else + retval=FAIL; + } + } + } + /*} else { + if (dim==Y) { + ret=nModY; + } else if (dim==X) { + ret=setNMod(-1); + } + } + */ + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + /*return ok/fail*/ + return retval; + +} + + +int get_max_number_of_modules(int file_des) { + int n; + int ret; + int retval=OK; + enum dimension arg; + + sprintf(mess,"Can't get max number of modules\n"); + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* execute action */ +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif + + + switch (arg) { + case X: + ret=getNModBoard(); + break; + case Y: + ret=NMAXMODY; + break; + default: + ret=FAIL; + retval=FAIL; + } +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,ret ); +#endif + + + + if (differentClients==1 && retval==OK) { + retval=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + + /*return ok/fail*/ + return retval; +} + + +//index 0 is in gate +//index 1 is in trigger +//index 2 is out gate +//index 3 is out trigger + +int set_external_signal_flag(int file_des) { + int n; + int arg[2]; + int ret=OK; + int signalindex; + enum externalSignalFlag flag, retval; + + sprintf(mess,"Can't set external signal flag\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + retval=SIGNAL_OFF; + if (ret==OK) { + signalindex=arg[0]; + flag=arg[1]; + /* execute action */ + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + + default: + if (differentClients==0 || lockStatus==0) { + retval=setExtSignal(signalindex,flag); + } else { + if (lockStatus!=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n", lastClientIP); + } + } + + + } + +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag ); + printf("Set to flag %d\n",retval); +#endif + + } else { + ret=FAIL; + } + + if (ret==OK && differentClients!=0) + ret=FORCE_UPDATE; + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + +int set_external_communication_mode(int file_des) { + int n; + enum externalCommunicationMode arg, ret=GET_EXTERNAL_COMMUNICATION_MODE; + int retval=OK; + + sprintf(mess,"Can't set external communication mode\n"); + + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } + /* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + GATE_COINCIDENCE_WITH_INTERNAL_ENABLE +}; + */ + if (retval==OK) { + /* execute action */ + + ret=setTiming(arg); + +/* switch(arg) { */ +/* default: */ +/* sprintf(mess,"The meaning of single signals should be set\n"); */ +/* retval=FAIL; */ +/* } */ + + +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif + } else + ret=FAIL; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&retval,sizeof(retval)); + if (retval!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&ret,sizeof(ret)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return retval; + + +} + + + +int get_id(int file_des) { + // sends back 64 bits! + int64_t retval, rev, dat; + int ret=OK; + int imod=-1; + int n=0; + int rev1; + enum idMode arg; + + sprintf(mess,"Can't return id\n"); + + /* receive arguments */ + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + + switch (arg) { + case MODULE_SERIAL_NUMBER: + n = receiveDataOnly(file_des,&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } else { +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + if (imod>=0 && imod<=getNModBoard()) { +#ifdef MCB_FUNCS + retval=getModuleNumber(imod); +#endif + ; + } + else { + sprintf(mess,"Module number %d out of range\n",imod); + ret=FAIL; + } + } + break; + case MODULE_FIRMWARE_VERSION: + retval=0x1; + break; + case DETECTOR_SERIAL_NUMBER: + retval=getMcsNumber(); + break; + case DETECTOR_FIRMWARE_VERSION: + retval=getMcsVersion(); + break; + case DETECTOR_SOFTWARE_VERSION: + retval= SVNREV; + retval= (retval <<32) | SVNDATE; +/* sscanf(THIS_REVISION,"$Rev : %x",&rev1); + rev=((int64_t)rev1); + dat=THIS_SOFTWARE_VERSION; + retval=(dat<<32) | rev; + */ + break; + default: + printf("Required unknown id %d \n", arg); + ret=FAIL; + retval=FAIL; + } + +#ifdef VERBOSE + printf("Id is %llx\n", retval); +#endif + + if (differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int digital_test(int file_des) { + + int retval; + int ret=OK; + int imod=-1; + int n=0; + int ibit=0; + int ow; + enum digitalTestMode arg; + + sprintf(mess,"Can't send digital test\n"); + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Digital test mode %d\n",arg ); +#endif + + switch (arg) { + case CHIP_TEST: + n = receiveDataOnly(file_des,&imod,sizeof(imod)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + retval=FAIL; + } +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + retval=0; +#ifdef MCB_FUNCS + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + break; + } + if (imod >= nModX) { + ret=FAIL; + sprintf(mess,"Module %d disabled\n",imod); + break; + } + if (testShiftIn(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftOut(imod)) retval|=(1<<(ibit)); + ibit++; + if (testShiftStSel(imod)) retval|=(1<<(ibit)); + ibit++; + //if ( testDataInOut(0x123456, imod)) retval|=(1<<(ibit++)); + //if ( testExtPulse(imod)) retval|=(1<<(ibit++)); + // for (ow=0; ow<6; ow++) + // ow=1; + //#ifndef PICASSOD + for (ow=0; ow<5; ow++) { + //#endif + if (testDataInOutMux(imod, ow, 0x789abc)) retval|=(1<=getNModBoard()) + ret=FAIL; + if (imod<0) + imod=ALLMOD; + +#ifdef MCB_FUNCS + switch (ind) { + case TRIMBIT_SIZE: + idac=VTRIM; + break; + case THRESHOLD: + idac=VTHRESH; + break; + case SHAPER1: + idac=RGSH1; + break; + case SHAPER2: + idac=RGSH2; + break; + case CALIBRATION_PULSE: + idac=VCAL; + break; + case PREAMP: + idac=RGPR; + break; + /*************************************************************** +add possible potentiometers like in chiptest board!!!!!!!!!!!!!!! + + ****************************************************************/ + + + + + default: + printf("Unknown DAC index %d\n",ind); + sprintf(mess,"Unknown DAC index %d\n",ind); + ret=FAIL; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1 && val!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + retval=initDACbyIndexDACU(idac,val,imod); + } +#endif + +#ifdef VERBOSE + printf("DAC set to %f V\n", retval); +#endif + if (retval==val || val==-1) { + ret=OK; + if (differentClients) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + printf("Setting dac %d of module %d: wrote %f but read %f\n", ind, imod, val, retval); + } + + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /* Maybe this is done inside the initialization funcs */ + //detectorDacs[imod][ind]=val; + /*return ok/fail*/ + return ret; + +} + + + +int get_adc(int file_des) { + + dacs_t retval; + int ret=OK; + int arg[2]; + enum dacIndex ind; + int imod; + int n; + int idac=0; + + sprintf(mess,"Can't read ADC\n"); + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ind=arg[0]; + imod=arg[1]; + + + if (imod>=getNModBoard() || imod<0) + ret=FAIL; + +#ifdef MCB_FUNCS + switch (ind) { + case TRIMBIT_SIZE: + idac=VTRIM; + break; + case THRESHOLD: + idac=VTHRESH; + break; + case SHAPER1: + idac=RGSH1; + break; + case SHAPER2: + idac=RGSH2; + break; + case CALIBRATION_PULSE: + idac=VCAL; + break; + case PREAMP: + idac=RGPR; + break; + default: + printf("Unknown DAC index %d\n",ind); + ret=FAIL; + sprintf(mess,"Unknown DAC index %d\n",ind); + } + + if (ret==OK) { + retval=getDACbyIndexDACU(idac,imod); + } + #endif +#ifdef VERBOSE + printf("Getting ADC %d of module %d\n", ind, imod); +#endif + +#ifdef VERBOSE + printf("ADC is %f V\n", retval); +#endif + if (ret==FAIL) { + printf("Getting adc %d of module %d failed\n", ind, imod); + } + + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + /*return ok/fail*/ + return ret; + +} + +int set_channel(int file_des) { + int ret=OK; + sls_detector_channel myChan; + int retval; + int n; + + + sprintf(mess,"Can't set channel\n"); + +#ifdef VERBOSE + printf("Setting channel\n"); +#endif + ret=receiveChannel(file_des, &myChan); + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif + + if (ret==OK) { + if (myChan.module>=getNModBoard()) + ret=FAIL; + if (myChan.chip>=NCHIP) + ret=FAIL; + if (myChan.chan>=NCHAN) + ret=FAIL; + if (myChan.module<0) + myChan.module=ALLMOD; + } + + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChannelbyNumber(myChan); +#endif + } + } + /* Maybe this is done inside the initialization funcs */ + //copyChannel(detectorChans[myChan.module][myChan.chip]+(myChan.chan), &myChan); + + + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + /*return ok/fail*/ + return ret; + +} + + + + +int get_channel(int file_des) { + + int ret=OK; + sls_detector_channel retval; + + int arg[3]; + int ichan, ichip, imod; + int n; + + sprintf(mess,"Can't get channel\n"); + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichan=arg[0]; + ichip=arg[1]; + imod=arg[2]; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0 && ichan=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + + if (ret==OK) { + if (myChip.module>=getNModBoard()) + ret=FAIL; + if (myChip.module<0) + myChip.module=ALLMOD; + if (myChip.chip>=NCHIP) + ret=FAIL; + } + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initChipbyNumber(myChip); +#endif + } + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + + + return ret; +} + +int get_chip(int file_des) { + + + int ret=OK; + sls_detector_chip retval; + int arg[2]; + int ichip, imod; + int n; + + + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ichip=arg[0]; + imod=arg[1]; + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod=0 && ichip=0) + ret=OK; + else + ret=FAIL; + + +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#endif + + if (ret==OK) { + if (myModule.module>=getNModBoard()) { + ret=FAIL; + printf("Module number is too large %d\n",myModule.module); + } + if (myModule.module<0) + myModule.module=ALLMOD; + } + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef MCB_FUNCS + retval=initModulebyNumber(myModule); +#endif + } + } + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret!=FAIL) { + /* send return argument */ + n += sendDataOnly(file_des,&retval,sizeof(retval)); + } else { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } + free(myChip); + free(myChan); + free(myDac); + free(myAdc); + + setDynamicRange(dr); + + + return ret; +} + + + + +int get_module(int file_des) { + + + int ret=OK; + + + int arg; + int imod; + int n; + + + + sls_detector_module myModule; + int *myChip=malloc(NCHIP*sizeof(int)); + int *myChan=malloc(NCHIP*NCHAN*sizeof(int)); + dacs_t *myDac=malloc(NDAC*sizeof(dacs_t)); + dacs_t *myAdc=malloc(NADC*sizeof(dacs_t)); + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } + + myModule.ndac=NDAC; + myModule.nchip=NCHIP; + myModule.nchan=NCHAN*NCHIP; + myModule.nadc=NADC; + + + + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + imod=arg; + + if (ret==OK) { + ret=FAIL; + if (imod>=0 && imod-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",getFrames()+2); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + } +#ifdef VERYVERBOSE + printf("%d %d %x %s\n",sizeof(mess),strlen(mess), mess,mess); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess));//sizeof(mess));//sizeof(mess)); +#ifdef VERYVERBOSE + printf("message sent\n",mess); +#endif + printf("dataret %d\n",dataret); + return dataret; + } + } else { + nframes=0; + while(fifo_read_event()) { + nframes++; + } + dataretval=(char*)ram_values; + dataret=OK; +#ifdef VERBOSE + printf("sending data of %d frames\n",nframes); +#endif + for (iframes=0; iframes-2) { + dataret=FAIL; + sprintf(mess,"no data and run stopped: %d frames left\n",getFrames()+2); + printf("%s\n",mess); + } else { + dataret=FINISHED; + sprintf(mess,"acquisition successfully finished\n"); + printf("%s\n",mess); + if (differentClients) + dataret=FORCE_UPDATE; + } +#ifdef VERBOSE + printf("Frames left %d\n",getFrames()); +#endif + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + printf("dataret %d\n",dataret); + return dataret; + } + printf("dataret %d\n",dataret); + return dataret; +} + + + + + + + + +int read_all(int file_des) { + + + while(read_frame(file_des)==OK) { +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } + +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + return OK; + + +} + +int start_and_read_all(int file_des) { + //int dataret=OK; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + if (differentClients==1 && lockStatus==1) { + dataret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + sendDataOnly(file_des,&dataret,sizeof(dataret)); + sendDataOnly(file_des,mess,sizeof(mess)); + return dataret; + + } + + + startStateMachine(); + /* ret=startStateMachine(); + if (ret!=OK) { + sprintf(mess,"could not start state machine\n"); + sendDataOnly(file_des,&ret,sizeof(ret)); + sendDataOnly(file_des,mess,sizeof(mess)); + + #ifdef VERBOSE + printf("could not start state machine\n"); +#endif +} else {*/ + read_all(file_des); +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + //} + + + return OK; + + +} + +int set_timer(int file_des) { + enum timerIndex ind; + int64_t tns; + int n; + int64_t retval; + int ret=OK; + + + sprintf(mess,"can't set timer\n"); + + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&tns,sizeof(tns)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret!=OK) { + printf(mess); + } + +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif + if (ret==OK) { + + if (differentClients==1 && lockStatus==1 && tns!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch(ind) { + case FRAME_NUMBER: + retval=setFrames(tns); + break; + case ACQUISITION_TIME: + retval=setExposureTime(tns); + break; + case FRAME_PERIOD: + retval=setPeriod(tns); + break; + case DELAY_AFTER_TRIGGER: + retval=setDelay(tns); + break; + case GATES_NUMBER: + retval=setGates(tns); + break; + case PROBES_NUMBER: + retval=setProbes(tns); + break; + case CYCLES_NUMBER: + retval=setTrains(tns); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + } + } + } + if (ret!=OK) { + printf(mess); + if (differentClients) + ret=FORCE_UPDATE; + } + + if (ret!=OK) { + printf(mess); + printf("set timer failed\n"); + sprintf(mess, "set timer %d failed\n", ind); + } else if (ind==FRAME_NUMBER) { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess, "could not allocate RAM for %lld frames\n", tns); + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { +#ifdef VERBOSE + printf("returning ok %d\n",sizeof(retval)); +#endif + + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + + return ret; + +} + + + + + + + + +int get_time_left(int file_des) { + + enum timerIndex ind; + int n; + int64_t retval; + int ret=OK; + + sprintf(mess,"can't get timer\n"); + n = receiveDataOnly(file_des,&ind,sizeof(ind)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + + printf("getting time left on timer %d \n",ind); +#endif + + if (ret==OK) { + switch(ind) { + case FRAME_NUMBER: + retval=getFrames(); + break; + case ACQUISITION_TIME: + retval=getExposureTime(); + break; + case FRAME_PERIOD: + retval=getPeriod(); + break; + case DELAY_AFTER_TRIGGER: + retval=getDelay(); + break; + case GATES_NUMBER: + retval=getGates(); + break; + case PROBES_NUMBER: + retval=getProbes(); + break; + case CYCLES_NUMBER: + retval=getTrains(); + break; + case PROGRESS: + retval=getProgress(); + break; + case ACTUAL_TIME: + retval=getActualTime(); + break; + case MEASUREMENT_TIME: + retval=getMeasurementTime(); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + } + } + + + if (ret!=OK) { + printf("get time left failed\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + +#ifdef VERBOSE + + printf("time left on timer %d is %lld\n",ind, retval); +#endif + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n += sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } +#ifdef VERBOSE + + printf("data sent\n"); +#endif + + return ret; + + +} + +int set_dynamic_range(int file_des) { + + + + int dr; + int n; + int retval; + int ret=OK; + + + sprintf(mess,"can't set dynamic range\n"); + + + n = receiveDataOnly(file_des,&dr,sizeof(dr)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + if (differentClients==1 && lockStatus==1 && dr>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setDynamicRange(dr); + } + + if (dr>=0 && retval!=dr) + ret=FAIL; + if (ret!=OK) { + sprintf(mess,"set dynamic range failed\n"); + } else { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess,"Could not allocate RAM for the dynamic range selected\n"); + else if (differentClients) + ret=FORCE_UPDATE; + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + +int set_roi(int file_des) { + + + int arg=-1; + int n; + ROI roiLimits[MAX_ROIS]; + int ret=OK; + ROI retval; + + int nm=setNMod(-1), nmax=getNModBoard(), nroi; + + + sprintf(mess,"can't set ROI\n"); + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if(arg>0){ + n+=receiveDataOnly(file_des,roiLimits,arg*sizeof(ROI)); + } + + if (arg>1) { + ret=FAIL; + sprintf(mess,"can't set more than 1 ROI per detector\n"); + + } else + ret=OK; + + if (arg>0) { + + nm=(roiLimits[0].xmax-1)/1280+1; + + if (roiLimits[0].xmin>0) { + roiLimits[0].xmin=0; + ret=FAIL; + sprintf(mess,"ROI starts at 0\n"); + } + + if (nm>nmax) { + retval.xmax=setNMod(-1)*1280; + ret=FAIL; + sprintf(mess,"ROI max larger than detector size\n"); + } + + } else if (arg==0) { + setNMod(nmax); + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + retval.xmin=0; + retval.xmax=setNMod(-1)*1280; + retval.ymin=0; + retval.ymax=0; + if (setNMod(-1)=0) { + if (differentClients==1 && lockStatus==1 && val>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch (arg) { + case CLOCK_DIVIDER: + retval=setClockDivider(val); + break; + case WAIT_STATES: + retval=setWaitStates(val); + break; + case SET_SIGNAL_LENGTH: + retval=setSetLength(val); + break; + case TOT_CLOCK_DIVIDER: + retval=setTotClockDivider(val); + break; + case TOT_DUTY_CYCLE: + retval=setTotDutyCycle(val); + break; + default: + ret=FAIL; + } + } + } else { + + switch (arg) { + case CLOCK_DIVIDER: + retval=getClockDivider(); + break; + case WAIT_STATES: + retval=getWaitStates(); + break; + case SET_SIGNAL_LENGTH: + retval=getSetLength(); + break; + case TOT_CLOCK_DIVIDER: + retval=getTotClockDivider(); + break; + case TOT_DUTY_CYCLE: + retval=getTotDutyCycle(); + break; + default: + ret=FAIL; + } + } + } + + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + +int set_readout_flags(int file_des) { + + enum readOutFlags retval; + enum readOutFlags arg; + int n; + int ret=OK; + int regret=OK; + + + sprintf(mess,"can't set readout flags\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting readout flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + //ret=setStoreInRAM(0); + // initChipWithProbes(0,0,0, ALLMOD); + switch(arg) { + case GET_READOUT_FLAGS: + break; + case STORE_IN_RAM: + if (setStoreInRAM(1)==OK) + ret=OK; + else + ret=FAIL; + break; + case TOT_MODE: + if(setToT(1)) + ret=OK; + else + ret=FAIL; + break; + case CONTINOUS_RO: + if (setContinousReadOut(1)) + ret=OK; + else + ret=FAIL; + break; + // case PUMP_PROBE_MODE: + //set number of probes + //initChipWithProbes(0,0,2, ALLMOD); + //break; + default: + ret=setStoreInRAM(0); + regret=setConfigurationRegister(0); + ret=OK; + } + } + retval=NORMAL_READOUT; + + if (storeInRAM) + retval=STORE_IN_RAM; + //else if (getProbes()) + // retval=PUMP_PROBE_MODE; + //else + if (setToT(-1)) + retval|=TOT_MODE; + if (setContinousReadOut(-1)) + retval|=CONTINOUS_RO; + if (ret!=OK) { + printf("set readout flags failed\n"); + sprintf(mess,"Could not allocate RAM\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + +int execute_trimming(int file_des) { + + int arg[3]; + int n; + int ret=OK; + int imod, par1,par2; + enum trimMode mode; + + printf("called function execute trimming\n"); + + sprintf(mess,"can't set execute trimming\n"); + + n = receiveDataOnly(file_des,&mode,sizeof(mode)); + printf("mode received\n"); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (mode)\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,arg,sizeof(arg)); + printf("arg received\n"); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (args)\n"); + ret=FAIL; + } + + imod=arg[0]; + + if (imod>=getNModBoard()) + ret=FAIL; + + if (imod<0) + imod=ALLMOD; + + par1=arg[1]; + par2=arg[2]; + +#ifdef VERBOSE + printf("trimming module %d mode %d, parameters %d %d \n",imod,mode, par1, par2); +#endif + + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + + if (ret==OK) { + switch(mode) { + case NOISE_TRIMMING: + // par1 is countlim; par2 is nsigma + ret=trim_with_noise(par1, par2, imod); + break; + case BEAM_TRIMMING: + // par1 is countlim; par2 is nsigma + ret=trim_with_beam(par1,par2,imod); + break; + case IMPROVE_TRIMMING: + // par1 is maxit; if par2!=0 vthresh will be optimized + ret=trim_improve(par1, par2,imod); + break; + case FIXEDSETTINGS_TRIMMING: + // par1 is countlim; if par2<0 then trimwithlevel else trim with median + ret=trim_fixed_settings(par1,par2,imod); + break; + // case OFFLINE_TRIMMING: + + //break; + default: + printf("Unknown trimming mode\n"); + sprintf(mess,"Unknown trimming mode\n"); + ret=FAIL; + } + } + } + + + if (ret<0) { + sprintf(mess,"can't set execute trimming\n"); + ret=FAIL; + } else if (ret>0) { + sprintf(mess,"Could not trim %d channels\n", ret); + ret=FAIL; + } else if (differentClients) + ret=FORCE_UPDATE; + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } + + return ret; +} + + +int lock_server(int file_des) { + + + int n; + int ret=OK; + + int lock; + n = receiveDataOnly(file_des,&lock,sizeof(lock)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (lock)\n"); + ret=FAIL; + } + if (lock>=0) { + if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) { + lockStatus=lock; + + } else { + ret=FAIL; + sprintf(mess,"Server already locked by %s\n", lastClientIP); + } + } + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else + n = sendDataOnly(file_des,&lockStatus,sizeof(lockStatus)); + + return ret; + +} + +int set_port(int file_des) { + int n; + int ret=OK; + int sd=-1; + + enum portType p_type; /** data? control? stop? Unused! */ + int p_number; /** new port number */ + + n = receiveDataOnly(file_des,&p_type,sizeof(p_type)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (ptype)\n"); + ret=FAIL; + } + + n = receiveDataOnly(file_des,&p_number,sizeof(p_number)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (pnum)\n"); + ret=FAIL; + } + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + printf("\n"); + ret=FAIL; + } + + printf("set port %d to %d\n",p_type, p_number); + + sd=bindSocket(p_number); + } + if (sd>=0 || sd==-10) { + ret=OK; + if (differentClients ) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + printf("Could not bind port %d\n", p_number); + + } + + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&p_number,sizeof(p_number)); + if (sd>=0) { + closeConnection(file_des); + exitServer(sockfd); + sockfd=sd; + } + + } + + return ret; + +} + +int get_last_client_ip(int file_des) { + int ret=OK; + int n; + if (differentClients ) + ret=FORCE_UPDATE; + n = sendDataOnly(file_des,&ret,sizeof(ret)); + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + + return ret; + +} + + +int send_update(int file_des) { + + int ret=OK; + enum detectorSettings t; + int thr, n; + // int it; + int64_t retval, tns=-1; + + + n = sendDataOnly(file_des,lastClientIP,sizeof(lastClientIP)); + n = sendDataOnly(file_des,&nModX,sizeof(nModX)); + // n = sendDataOnly(file_des,&nModY,sizeof(nModY)); + //sends back max modules instead of nmodulesY! + + thr = getNModBoard(); + sendDataOnly(file_des,&thr,sizeof(thr)); + + n = sendDataOnly(file_des,&dynamicRange,sizeof(dynamicRange)); + n = sendDataOnly(file_des,&dataBytes,sizeof(dataBytes)); + t=setSettings(GET_SETTINGS); + n = sendDataOnly(file_des,&t,sizeof(t)); + thr=getThresholdEnergy(); + n = sendDataOnly(file_des,&thr,sizeof(thr)); + retval=setFrames(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setExposureTime(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setPeriod(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setDelay(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setGates(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setProbes(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + retval=setTrains(tns); + n = sendDataOnly(file_des,&retval,sizeof(int64_t)); + + if (lockStatus==0) { + strcpy(lastClientIP,thisClientIP); + } + + return ret; + + +} +int update_client(int file_des) { + + int ret=OK; + + sendDataOnly(file_des,&ret,sizeof(ret)); + return send_update(file_des); + + + +} + + +int set_master(int file_des) { + + enum masterFlags retval=GET_MASTER; + enum masterFlags arg; + int n; + int ret=OK; + // int regret=OK; + + + sprintf(mess,"can't set master flags\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setMaster(arg); + + } + if (retval==GET_MASTER) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} + + + + + + +int set_synchronization(int file_des) { + + enum synchronizationMode retval=GET_MASTER; + enum synchronizationMode arg; + int n; + int ret=OK; + //int regret=OK; + + + sprintf(mess,"can't set synchronization mode\n"); + + + n = receiveDataOnly(file_des,&arg,sizeof(arg)); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + //ret=setStoreInRAM(0); + // initChipWithProbes(0,0,0, ALLMOD); + retval=setSynchronization(arg); + } + if (retval==GET_SYNCHRONIZATION_MODE) { + ret=FAIL; + } + n = sendDataOnly(file_des,&ret,sizeof(ret)); + if (ret==FAIL) { + n = sendDataOnly(file_des,mess,sizeof(mess)); + } else { + n = sendDataOnly(file_des,&retval,sizeof(retval)); + } + return ret; +} diff --git a/slsDetectorSoftware/mythenDetectorServer/server_funcs.h b/slsDetectorSoftware/mythenDetectorServer/server_funcs.h new file mode 100755 index 000000000..7a458e9cd --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/server_funcs.h @@ -0,0 +1,79 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H +#include +/* +#include +#include +#include +*/ +#include "communication_funcs.h" + + + + +#define GOODBYE -200 + +int sockfd; + +int function_table(); + +int decode_function(int); + +int init_detector(int); + +int M_nofunc(int); +int exit_server(int); + + + + + // General purpose functions +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); + + +int exec_command(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +int write_register(int); +int read_register(int); +int set_dac(int); +int get_adc(int); +int set_channel(int); +int set_chip(int); +int set_module(int); +int get_channel(int); +int get_chip(int); +int get_module(int); + +int get_threshold_energy(int); +int set_threshold_energy(int); +int set_settings(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int read_frame(int); +int read_all(int); +int start_and_read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_roi(int); +int get_roi(int); +int set_speed(int); +int set_readout_flags(int); +int execute_trimming(int); +int lock_server(int); +int set_port(int); +int get_last_client_ip(int); +int set_master(int); +int set_synchronization(int); + +int update_client(int); +int send_update(int); + +#endif diff --git a/slsDetectorSoftware/mythenDetectorServer/sharedmemory.c b/slsDetectorSoftware/mythenDetectorServer/sharedmemory.c new file mode 100755 index 000000000..302a0308c --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/sharedmemory.c @@ -0,0 +1,46 @@ +#include "sharedmemory.h" + +struct statusdata *stdata; + +int inism(int clsv) { + +static int scansmid; + + if (clsv==SMSV) { + if ( (scansmid=shmget(SMKEY,1024,IPC_CREAT | 0666 ))==-1 ) { + return -1; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -2; + } + } + + if (clsv==SMCL) { + if ( (scansmid=shmget(SMKEY,0,0) )==-1 ) { + return -3; + } + if ( (stdata=shmat(scansmid,NULL,0))==(void*)-1) { + return -4; + } + } + return 1; +} + +void write_status_sm(char *status) { + strcpy(stdata->status,status); +} + +void write_istatus_sm(int i) { + stdata->istatus=i; +} +int read_istatus_sm() { + return stdata->istatus; +} + +void write_stop_sm(int v) { + stdata->stop=v; +} + +void write_runnumber_sm(int v) { + stdata->runnumber=v; +} diff --git a/slsDetectorSoftware/mythenDetectorServer/sharedmemory.h b/slsDetectorSoftware/mythenDetectorServer/sharedmemory.h new file mode 100755 index 000000000..d50eb5047 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/sharedmemory.h @@ -0,0 +1,52 @@ +#ifndef SM +#define SM + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + +#include +#include + +/* key for shared memory */ +#define SMKEY 10001 + +#define SMSV 1 +#define SMCL 2 + + +struct statusdata { + int runnumber; + int stop; + int istatus; + char status[20]; +} ; + + +/* for shared memory */ + +int inism(int clsv); +void write_status_sm(char *status); +void write_stop_sm(int v); +void write_runnumber_sm(int v); + +void write_istatus_sm(int v); + +int read_istatus_sm(); + +#endif diff --git a/slsDetectorSoftware/mythenDetectorServer/sls_detector_defs.h b/slsDetectorSoftware/mythenDetectorServer/sls_detector_defs.h new file mode 120000 index 000000000..c5062e03f --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/sls_detector_defs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/mythenDetectorServer/sls_detector_funcs.h b/slsDetectorSoftware/mythenDetectorServer/sls_detector_funcs.h new file mode 120000 index 000000000..844b67129 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/sls_detector_funcs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/mythenDetectorServer/sls_receiver_defs.h b/slsDetectorSoftware/mythenDetectorServer/sls_receiver_defs.h new file mode 120000 index 000000000..1de31caf5 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/sls_receiver_defs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/mythenDetectorServer/sls_receiver_funcs.h b/slsDetectorSoftware/mythenDetectorServer/sls_receiver_funcs.h new file mode 120000 index 000000000..c2ea4ded9 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/sls_receiver_funcs.h @@ -0,0 +1 @@ +../../slsReceiverSoftware/include/sls_receiver_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/mythenDetectorServer/stop_server.c b/slsDetectorSoftware/mythenDetectorServer/stop_server.c new file mode 100755 index 000000000..571c9a978 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/stop_server.c @@ -0,0 +1,41 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ +#include "communication_funcs.h" +#include "firmware_funcs.h" + + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + + portno = DEFAULT_PORTNO; + + + bindSocket(portno); + if (getServerError()) + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + acceptConnection(); + retval=stopStateMachine(); + closeConnection(); + } + + exitServer(); + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.c b/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.c new file mode 100755 index 000000000..b86e9f3f4 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.c @@ -0,0 +1,789 @@ +#ifndef PICASSOD +#include "server_defs.h" +#else +#include "picasso_defs.h" +#endif +#include "trimming_funcs.h" +#include "mcb_funcs.h" +#include "firmware_funcs.h" +#include + + + +extern int nModX; +//extern int *values; + +extern const int nChans; +extern const int nChips; +extern const int nDacs; +extern const int nAdcs; + + +int trim_fixed_settings(int countlim, int par2, int im) +{ + + int retval=OK; +#ifdef VERBOSE + printf("Trimming with fixed settings\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + if (par2<=0) + retval=trim_with_level(countlim, im); + else + retval=trim_with_median(countlim,im); + + + return retval; +} + + +int trim_with_noise(int countlim, int nsigma, int im) +{ + + + int retval1=OK, retval2=OK; +#ifdef VERBOSE + printf("Trimming using noise\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + /* threshold scan */ + +#ifdef VERBOSE + printf("chosing vthresh and vtrim....."); +#endif + retval1=choose_vthresh_and_vtrim(countlim,nsigma, im); + +#ifdef VERBOSE + printf("trimming with noise.....\n"); +#endif + if (retval1==OK) + retval2=trim_with_level(countlim, im); + else + retval2=-1; + +#ifdef DEBUGOUT + printf("done\n"); +#endif + //if (retval1==OK && retval2==OK) + // retval=OK; + //else + // retval=FAIL; + + return retval2; + +} + +int trim_with_beam(int countlim, int nsigma, int im) //rpc +{ + + + int retval1=OK, retval2=OK; + + printf("Trimming using beam\n"); + //return OK; +#ifdef VIRTUAL + printf("Trimming using beam\n"); + return OK; +#endif + /* threshold scan */ +#ifdef DEBUGOUT + printf("chosing vthresh and vtrim....."); +#endif + + retval1=choose_vthresh_and_vtrim(countlim,nsigma,im); + if (retval1==OK) + retval2=trim_with_median(TRIM_DR, im); + else return -1; + +#ifdef DEBUGOUT + printf("done\n"); +#endif + + // if (retval1==OK && retval2==OK) + // retval=OK; + //else + // retval=FAIL; + + return retval2; + +} + + +int trim_improve(int maxit, int par2, int im) //rpc +{ + + int retval1=OK, retval2=OK; + + +#ifdef VERBOSE + printf("Improve the trimming\n"); +#endif +#ifdef VIRTUAL + return OK; +#endif + + + if (par2!=0 && im==ALLMOD) + retval1=choose_vthresh(); + if (retval1==OK) + retval2=trim_with_median(2*maxit+1, im); + else + return -1; +#ifdef DEBUGOUT + printf("done\n"); +#endif + // if (retval1==OK && retval2==OK) + // retval=OK; + //else + //retval=FAIL; + + return retval2; + +} + +int calcthr_from_vcal(int vcal) { + int thrmin; + //thrmin=140+3*vcal/5; + thrmin=180+3*vcal/5; + return thrmin; +} + +int calccal_from_vthr(int vthr) { + int vcal; + vcal=5*(vthr-140)/3; + return vcal; +} + +int choose_vthresh_and_vtrim(int countlim, int nsigma, int im) { + int retval=OK; +#ifdef MCB_FUNCS + int modma, modmi, nm; + int thr, thrstep=5, nthr=31; + + int *fifodata; + + float vthreshmean, vthreshSTDev; + int *thrmi, *thrma; + float c; + float b=BVTRIM; + float a=AVTRIM; + int *trim; + int ich, imod, ichan; + int nvalid=0; + u_int32_t *scan; + int ithr; + sls_detector_channel myChan; + + + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + trim=malloc(sizeof(int)*nChans*nChips*nModX); + thrmi=malloc(sizeof(int)*nModX); + thrma=malloc(sizeof(int)*nModX); + + + for (ich=0; ichcountlim && trim[ich]==-1) { + trim[ich]=getDACbyIndexDACU(VTHRESH,imod); +#ifdef VERBOSE + // printf("yes: %d %d %d\n",ich,ithr,scan[ich]); +#endif + } +#ifdef VERBOSE + /* else { + printf("no: %d %d %d\n",ich,ithr,scan[ich]); + }*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imodthrmi[imod] && trim[ich]0) { + vthreshmean=vthreshmean/nvalid; + vthreshSTDev=sqrt((vthreshSTDev/nvalid)-vthreshmean*vthreshmean); + } else { + vthreshmean=thrmi[imod]; + vthreshSTDev=nthr*thrstep; + printf("No valid channel for module %d\n",imod); + retval=FAIL; + } + +#ifdef DEBUGOUT + printf("module= %d nvalid = %d mean=%f RMS=%f\n",imod, nvalid, vthreshmean,vthreshSTDev); +#endif + // *vthresh=round(vthreshmean-nsigma*vthreshSTDev); + thr=(int)(vthreshmean-nsigma*vthreshSTDev); + if (thr<0 || thr>(DAC_DR-1)) { + thr=thrmi[imod]/2; + printf("Can't find correct threshold for module %d\n",imod); + retval=FAIL; + } + initDACbyIndexDACU(VTHRESH,thr,imod); +#ifdef VERBOSE + printf("vthresh=%d \n",thr); +#endif + c=CVTRIM-2.*nsigma*vthreshSTDev/63.; + thr=(int)((-b-sqrt(b*b-4*a*c))/(2*a)); + if (thr<500 || thr>(DAC_DR-1)) { + thr=750; + printf("Can't find correct trimbit size for module %d\n",imod); + retval=FAIL; + } + + initDACbyIndexDACU(VTRIM,thr,imod); + +#ifdef VERBOSE + printf("vtrim=%d \n",thr); +#endif + + } + free(trim); + free(thrmi); + free(thrma); + +#endif + return retval; +} + + + + + +int trim_with_level(int countlim, int im) { + int ich, itrim, ichan, ichip, imod; + u_int32_t *scan; + int *inttrim; + int modma, modmi, nm; + int retval=0; + int *fifodata; + sls_detector_channel myChan; + printf("trimming module number %d", im); + + +#ifdef MCB_FUNCS + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + inttrim=malloc(sizeof(int)*nChips*nChans*nModX); + printf("countlim=%d\n",countlim); + for (ich=0; ichcountlim){ + inttrim[ich]=itrim; + if (scan[ich]>2*countlim && itrim>0) { + //if (scan[ich]>2*countlim || itrim==0) { + inttrim[ich]=itrim-1; + } +#ifdef VERBOSE + printf("Channel %d trimbit %d counted %d (%08x) countlim %d\n",ich,itrim,scan[ich],fifodata[ich],countlim); +#endif + } + } +#ifdef VERBOSE + /* else + printf("Channel %d trimbit %d counted %d countlim %d\n",ich,itrim,scan[ich],countlim);*/ +#endif + } + } + free(scan); + } + + for (imod=modmi; imod0) + direction[ichan]=1; + else + direction[ichan]=-1; + } + vthresh=getDACbyIndexDACU(VTHRESH,imod); + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + vthresh=vthresh-direction[ichan]; + if (vthresh>(DAC_DR-1)) { + vthresh=(DAC_DR-1); + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + if (vthresh<0) { + vthresh=0; + printf("can't equalize threshold for module %d\n", ichan); + retval=FAIL; + } + direction[ichan]=-3; + } else { + vthresh=vthresh+direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } + initDACbyIndex(VTHRESH,vthresh, ichan); + } + } + iteration++; + free(scan); + free(scan1); + } +#endif + return retval; +} + + + + + +int trim_with_median(int stop, int im) { + + + int retval=0; + +#ifdef MCB_FUNCS + int ichan, imod, ichip, ich; + u_int32_t *scan, *scan1; + int *olddiff, *direction; + int med, diff; + int change_flag=1; + int iteration=0; + int me[nModX], me1[nModX]; + int modma, modmi, nm; + int trim; + int *fifodata; + + setFrames(1); + // setNMod(getNModBoard()); + + if (im==ALLMOD){ + modmi=0; + modma=nModX; + } else { + modmi=im; + modma=im+1; + } + nm=modma-modmi; + + olddiff=malloc(4*nModX*nChips*nChans); + direction=malloc(4*nModX*nChips*nChans); + for (imod=modmi; imod0) { + direction[ichan]=1; + } else { + direction[ichan]=-1; + } + } + if ( direction[ichan]!=-3) { + if (abs(diff)>abs(olddiff[ichan])) { + trim=getTrimbit(imod,ichip,ich)+direction[ichan]; + printf("%d old diff %d < new diff %d %d - trimbit %d\n",ichan, olddiff[ichan], diff, direction[ichan], trim); + direction[ichan]=-3; + } else { + trim=getTrimbit(imod,ichip,ich)-direction[ichan]; + olddiff[ichan]=diff; + change_flag=1; + } + if (trim>TRIM_DR) { + trim=63; + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + retval++; + } + if (trim<0) { + printf("can't trim channel %d chip %d module %d to trim %d\n",ich, ichip, imod, trim); + trim=0; + retval++; + } + initChannel(trim,0,0,1,0,0,imod); + } + } + } + } + iteration++; + free(scan); + free(scan1); + } + free(olddiff); + free(direction); +#endif + return retval; +} diff --git a/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.h b/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.h new file mode 100755 index 000000000..ac73dcaa1 --- /dev/null +++ b/slsDetectorSoftware/mythenDetectorServer/trimming_funcs.h @@ -0,0 +1,17 @@ +#ifndef TRIMMING_FUNCS_H +#define TRIMMING_FUNCS_H +int trim_fixed_settings(int countlim, int par2, int imod); +int trim_with_noise(int countlim, int nsigma, int imod); +int trim_with_beam(int countlim, int nsigma, int imod); +int trim_improve(int maxit, int par2, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); +int choose_vthresh_and_vtrim(int countlim, int nsigma, int imod); + +int choose_vthresh(); +int trim_with_level(int countlim, int imod); +int trim_with_median(int stop, int imod); +int calcthr_from_vcal(int vcal); +int calccal_from_vthr(int vthr); +int median(int *a,int n); +#endif diff --git a/slsDetectorSoftware/patternGenerator/generate.sh b/slsDetectorSoftware/patternGenerator/generate.sh new file mode 100755 index 000000000..f7aac61c4 --- /dev/null +++ b/slsDetectorSoftware/patternGenerator/generate.sh @@ -0,0 +1,30 @@ +if [ "$#" -eq 0 ]; then + echo "Wrong number of arguments: usage should be $0 patname" + exit 1 +fi +infile=$1 +outfile=$infile"at" +outfilebin=$infile"bin" +if [ "$#" -ge 2 ]; then + outfile=$2 +fi +exe=$infile"exe" +if [ "$#" -ge 4 ]; then + exe=$4 +fi + +if [ "$#" -ge 3 ]; then + outfilebin=$3 +fi + +if [ -f "$infile" ] +then +gcc -DINFILE="\"$infile\"" -DOUTFILE="\"$outfile\"" -DOUTFILEBIN="\"$outfilebin\"" -o $exe generator.c ; +echo compiling +$exe ; +echo cleaning +rm $exe +echo done +else + echo "$infile not found." +fi diff --git a/slsDetectorSoftware/patternGenerator/generator.c b/slsDetectorSoftware/patternGenerator/generator.c new file mode 100755 index 000000000..24b192844 --- /dev/null +++ b/slsDetectorSoftware/patternGenerator/generator.c @@ -0,0 +1,162 @@ +/**************************************************************************** +usage to generate a patter test.pat from test.p + +gcc -DINFILE="\"test.p\"" -DOUTFILE="\"test.pat\"" -o test.exe generator.c ; ./test.exe ; rm test.exe + + +*************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLOOPS 3 +#define MAXTIMERS 3 +#define MAXWORDS 1024 + + + +uint64_t pat=0; +uint64_t iopat=0; +uint64_t clkpat=0; + +int iaddr=0; +int waitaddr[3]={MAXWORDS,MAXWORDS,MAXWORDS}; +int startloopaddr[3]={MAXWORDS,MAXWORDS,MAXWORDS}; +int stoploopaddr[3]={MAXWORDS,MAXWORDS,MAXWORDS}; +int start=0, stop=0; +uint64_t waittime[3]={0,0,0}; +int nloop[3]={0,0,0}; + +char infile[10000], outfile[10000]; + +FILE *fd, *fd1; +uint64_t PAT[MAXWORDS]; + + +int i,ii,iii,j,jj,jjj,pixx,pixy,memx,memy,muxout,memclk,colclk,rowclk,muxclk,memcol,memrow,loopcounter; + +void setstart() { + start=iaddr; +} + +void setstop() { + stop=iaddr; +} + +void setinput(int bit) { + uint64_t mask=1; + mask=mask<>bit; +} + +void setstartloop(int iloop) { + if (iloop>=0 && iloop=0 && iloop=0 && iloop=0 && iloop=0 && iloop=MAXWORDS) printf("ERROR: too many word in the pattern (%d instead of %d)!",iaddr, MAXWORDS); +} + + + + +main(void) { + int iloop=0; + fd=fopen(OUTFILE,"w"); +#include INFILE + + fprintf(fd,"patioctrl %016llx\n",iopat); + fprintf(fd,"patclkctrl %016llx\n",clkpat); + fprintf(fd,"patlimits %04x %04x\n",start, stop); + + for (iloop=0; iloop +#include +#include +#include +#include +#include +#include +#include "gitInfoLib.h" + + +int slsDetector::initSharedMemory(detectorType type, int id) { + + + /** + the shared memory key is set to DEFAULT_SHM_KEY+id + */ + key_t mem_key=DEFAULT_SHM_KEY+id; + int shm_id; + int nch, nm, nc, nd, ng, no; + int sz; + + //shmId=-1; + + switch(type) { + case MYTHEN: + nch=128; // complete mythen system + nm=24; + nc=10; + nd=6; // dacs+adcs + ng=0; + no=0; + break; + case PICASSO: + nch=128; // complete mythen system + nm=24; + nc=12; + nd=6; // dacs+adcs + ng=0; + no=0; + break; + case GOTTHARD: + nch=128; + nm=1; + nc=10; + nd=13; // dacs+adcs + ng=0; + no=0; + break; + case PROPIX: + nch=22*22; + nm=1; + nc=1; + nd=13; // dacs+adcs + break; + case EIGER: + nch=256*256; // one EIGER half module + nm=1; //modules/detector + nc=4; //chips + nd=16; //dacs+adcs + ng=4; + no=4; + break; + case MOENCH: + nch=160*160; + nm=1; //modules/detector + nc=1; //chips + nd=9; //dacs+adcs + ng=0; + no=0; + break; + case JUNGFRAU: + nch=256*256; + nm=1; //modules/detector + nc=8; //chips + nd=16; //dacs+adcs + ng=0; + no=0; + break; + case JUNGFRAUCTB: + nch=32; + nm=1; //modules/detector + nc=1; //chips + nd=16; //dacs+adcs + ng=0; + no=0; + break; + default: + nch=0; // dum! + nm=0; //modules/detector + nc=0; //chips + nd=0; //dacs+adcs + ng=0; + no=0; + break; + } + /** + The size of the shared memory is: + size of shared structure + ffcoefficents +fferrors + modules+ dacs+adcs+chips+chans+gain+offset + */ + + + sz=sizeof(sharedSlsDetector)+nm*(2*nch*nc*sizeof(double)+sizeof(sls_detector_module)+sizeof(int)*nc+sizeof(dacs_t)*nd+sizeof(int)*nch*nc+sizeof(int)*ng+sizeof(int)*no); +#ifdef VERBOSE + std::cout<<"Size of shared memory is "<< sz << "(type " << type << " - id " << mem_key << ")"<< std::endl; +#endif + shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory + + if (shm_id < 0) { + std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; + return shm_id; + } + + /** + thisDetector pointer is set to the memory address of the shared memory + */ + + thisDetector = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ + + if (thisDetector == (void*)-1) { + std::cout<<"*** shmat error (server) ***" << std::endl; + return shm_id; + } + + + /** + shm_id returns -1 is shared memory initialization fails + */ + //shmId=shm_id; + return shm_id; + +} + + +int slsDetector::freeSharedMemory() { + // Detach Memory address + if (shmdt(thisDetector) == -1) { + perror("shmdt failed\n"); + return FAIL; + } + printf("Shared memory %d detached\n", shmId); + // remove shared memory + if (shmctl(shmId, IPC_RMID, 0) == -1) { + perror("shmctl(IPC_RMID) failed\n"); + return FAIL; + } + printf("Shared memory %d deleted\n", shmId); + return OK; +} + + + +slsDetector::slsDetector(int id,multiSlsDetector *p) :slsDetectorUtils(), + thisDetector(NULL), + detId(id), + parentDet(p), + shmId(-1), + controlSocket(NULL), + stopSocket(NULL), + dataSocket(NULL), + ffcoefficients(NULL), + fferrors(NULL), + detectorModules(NULL), + dacs(NULL), + adcs(NULL), + chipregs(NULL), + chanregs(NULL), + gain(NULL), + offset(NULL), + thisReceiver(NULL) + + +{ + + + detectorType type=(detectorType)getDetectorType(id); + + while (shmId<0) { + /**Initlializes shared memory \sa initSharedMemory + + if it fails the detector id is incremented until it succeeds + */ + shmId=initSharedMemory(type,id); + id++; + } + id--; +#ifdef VERBOSE + std::cout<< "Detector id is " << id << std::endl; +#endif + detId=id; + + + /**Initializes the detector stucture \sa initializeDetectorSize + */ + initializeDetectorSize(type); + + + +}; + + + + + +slsDetector::slsDetector(detectorType type, int id,multiSlsDetector *p): slsDetectorUtils(), + thisDetector(NULL), + detId(id), + parentDet(p), + shmId(-1), + controlSocket(NULL), + stopSocket(NULL), + dataSocket(NULL), + ffcoefficients(NULL), + fferrors(NULL), + detectorModules(NULL), + dacs(NULL), + adcs(NULL), + chipregs(NULL), + chanregs(NULL), + gain(NULL), + offset(NULL), + thisReceiver(NULL) + +{ + while (shmId<0) { + /**Initlializes shared memory \sa initSharedMemory + + if it fails the detector id is incremented until it succeeds + */ + shmId=initSharedMemory(type,id); + id++; + } + id--; +#ifdef VERBOSE + std::cout<< "Detector id is " << id << " type is " << type << std::endl; +#endif + detId=id; + + + /**Initializes the detector stucture \sa initializeDetectorSize + */ + initializeDetectorSize(type); + + + +} + + +slsDetector::~slsDetector(){ + + // Detach Memory address + if (shmdt(thisDetector) == -1) { + perror("shmdt failed\n"); + printf("Could not detach shared memory %d\n", shmId); + } else + printf("Shared memory %d detached\n", shmId); + +delete thisReceiver; +}; + +slsDetector::slsDetector(char *name, int id, int cport,multiSlsDetector *p) : slsDetectorUtils(), + thisDetector(NULL), + detId(id), + parentDet(p), + shmId(-1), + controlSocket(NULL), + stopSocket(NULL), + dataSocket(NULL), + ffcoefficients(NULL), + fferrors(NULL), + detectorModules(NULL), + dacs(NULL), + adcs(NULL), + chipregs(NULL), + chanregs(NULL), + gain(NULL), + offset(NULL), + thisReceiver(NULL) + + +{ + detectorType type=(detectorType)getDetectorType(name, cport); + + + while (shmId<0) { + /**Initlializes shared memory \sa initSharedMemory + + if it fails the detector id is incremented until it succeeds + */ + shmId=initSharedMemory(type,id); + id++; + } + id--; +#ifdef VERBOSE + std::cout<< "Detector id is " << id << std::endl; +#endif + detId=id; + + + /**Initializes the detector stucture \sa initializeDetectorSize + */ + initializeDetectorSize(type); + + + + + + setTCPSocket(name, cport); + updateDetector(); + +} + +slsDetectorDefs::detectorType slsDetector::getDetectorType(const char *name, int cport) { + + int retval=FAIL; + detectorType t=GENERIC; + int fnum=F_GET_DETECTOR_TYPE; + MySocketTCP *s= new MySocketTCP(name, cport); + char m[100]; +#ifdef VERBOSE + cout << "Getting detector type " << endl; +#endif + if (s->Connect()>=0) { + s->SendDataOnly(&fnum,sizeof(fnum)); + s->ReceiveDataOnly(&retval,sizeof(retval)); + + if (retval!=FAIL) { + s->ReceiveDataOnly(&t,sizeof(t)); + +#ifdef VERBOSE + cout << "Detector type is "<< t << endl; +#endif + + } else { + s->ReceiveDataOnly(m,sizeof(m)); + std::cout<< "Detector returned error: " << m << std::endl; + } + s->Disconnect(); + } else { + cout << "Cannot connect to server " << name << " over port " << cport << endl; + } + + +/* + //receiver + if((t != GENERIC) && (setReceiverOnline()==ONLINE_FLAG)) { + int k; + retval = FAIL; + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending detector type to Receiver " << (int)thisDetector->myDetectorType << std::endl; +#endif + if (connectData() == OK) + retval=thisReceiver->sendInt(fnum2,k,(int)t); + disconnectData(); + if(retval==FAIL){ + cout << "ERROR: Could not send detector type to receiver" << endl; + setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); + } + } + } +*/ + delete s; + return t; + +} + + + + + + + + +int slsDetector::exists(int id) { + + key_t mem_key=DEFAULT_SHM_KEY+id; + int shm_id; + int sz; + + sz=sizeof(sharedSlsDetector); + + +#ifdef VERBOSE + cout << "getDetectorType: generic shared memory of size " << sz << endl; +#endif + shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory + + if (shm_id < 0) { + std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; + return -1; + } + + /** + thisDetector pointer is set to the memory address of the shared memory + */ + + sharedSlsDetector* det = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ + + if (det == (void*)-1) { + std::cout<<"*** shmat error (server) ***" << std::endl; + return -1; + } + /** + shm_id returns -1 is shared memory initialization fails + */ + //shmId=shm_id; + + + + + if (det->alreadyExisting==0) { + // Detach Memory address + if (shmdt(det) == -1) { + perror("shmdt failed\n"); + return 0; + } +#ifdef VERBOSE + printf("Shared memory %d detached\n", shm_id); +#endif + // remove shared memory + if (shmctl(shm_id, IPC_RMID, 0) == -1) { + perror("shmctl(IPC_RMID) failed\n"); + return 0; + } +#ifdef VERBOSE + printf("Shared memory %d deleted\n", shm_id); +#endif + return 0; + } + + return 1; + + + +} + + + + + +slsDetectorDefs::detectorType slsDetector::getDetectorType(int id) { + + detectorType t=GENERIC; + + + key_t mem_key=DEFAULT_SHM_KEY+id; + int shm_id; + int sz; + + sz=sizeof(sharedSlsDetector); + + +#ifdef VERBOSE + cout << "getDetectorType: generic shared memory of size " << sz << endl; +#endif + shm_id = shmget(mem_key,sz,IPC_CREAT | 0666); // allocate shared memory + + if (shm_id < 0) { + std::cout<<"*** shmget error (server) ***"<< shm_id << std::endl; + return t; + } + + /** + thisDetector pointer is set to the memory address of the shared memory + */ + + sharedSlsDetector* det = (sharedSlsDetector*) shmat(shm_id, NULL, 0); /* attach */ + + if (det == (void*)-1) { + std::cout<<"*** shmat error (server) ***" << std::endl; + return t; + } + /** + shm_id returns -1 is shared memory initialization fails + */ + //shmId=shm_id; + + t=det->myDetectorType; + + + if (det->alreadyExisting==0) { + // Detach Memory address + if (shmdt(det) == -1) { + perror("shmdt failed\n"); + return t; + } +#ifdef VERBOSE + printf("Shared memory %d detached\n", shm_id); +#endif + // remove shared memory + if (shmctl(shm_id, IPC_RMID, 0) == -1) { + perror("shmctl(IPC_RMID) failed\n"); + return t; + } +#ifdef VERBOSE + printf("Shared memory %d deleted\n", shm_id); +#endif + } + +#ifdef VERBOSE + cout << "Detector type is " << t << endl; +#endif + + return t; + + +} + + +int slsDetector::initializeDetectorSize(detectorType type) { + char *goff; + goff=(char*)thisDetector; + + // cout << "init detector size" << endl; + + /** if the shared memory has newly be created, initialize the detector variables */ + if (thisDetector->alreadyExisting==0) { + + // cout << "detector not existing " << endl; + + /** set hostname to default */ + strcpy(thisDetector->hostname,DEFAULT_HOSTNAME); + + /** set receiver tcp port */ + thisDetector->receiverTCPPort=DEFAULT_PORTNO+2; + /** set receiver udp port */ + thisDetector->receiverUDPPort=DEFAULT_UDP_PORTNO; + /** set receiver udp port for Eiger */ + thisDetector->receiverUDPPort2=DEFAULT_UDP_PORTNO+1; + /** set receiver ip address/hostname */ + strcpy(thisDetector->receiver_hostname,"none"); + /** set receiver udp ip address */ + strcpy(thisDetector->receiverUDPIP,"none"); + /** set receiver udp mac address */ + strcpy(thisDetector->receiverUDPMAC,"none"); + /** set detector mac address */ + strcpy(thisDetector->detectorMAC,DEFAULT_DET_MAC); + /** set detector ip address */ + strcpy(thisDetector->detectorIP,DEFAULT_DET_IP); + + /** sets onlineFlag to OFFLINE_FLAG */ + thisDetector->onlineFlag=OFFLINE_FLAG; + /** set ports to defaults */ + thisDetector->controlPort=DEFAULT_PORTNO; + thisDetector->stopPort=DEFAULT_PORTNO+1; + + /** set thisDetector->myDetectorType to type and according to this set nChans, nChips, nDacs, nAdcs, nModMax, dynamicRange, nMod*/ + thisDetector->myDetectorType=type; + switch(thisDetector->myDetectorType) { + case MYTHEN: + thisDetector->nChan[X]=128; + thisDetector->nChan[Y]=1; + thisDetector->nChip[X]=10; + thisDetector->nChip[Y]=1; + thisDetector->nDacs=6; + thisDetector->nAdcs=0; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=24; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=24; + thisDetector->moveFlag=1; +#ifdef VERBOSE + cout << "move flag" << thisDetector->moveFlag<< endl; +#endif + break; + case PICASSO: + thisDetector->nChan[X]=128; + thisDetector->nChan[Y]=1; + thisDetector->nChip[X]=12; + thisDetector->nChip[Y]=1; + thisDetector->nDacs=6; + thisDetector->nAdcs=0; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=6; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=24; + break; + case GOTTHARD: + thisDetector->nChan[X]=128; + thisDetector->nChan[Y]=1; + thisDetector->nChip[X]=10; + thisDetector->nChip[Y]=1; + thisDetector->nDacs=8; + thisDetector->nAdcs=5; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=1; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=16; + break; + case PROPIX: + thisDetector->nChan[X]=22; + thisDetector->nChan[Y]=22; + thisDetector->nChip[X]=1; + thisDetector->nChip[Y]=1; + thisDetector->nDacs=8; + thisDetector->nAdcs=5; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=1; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=16; + break; + case MOENCH: + thisDetector->nChan[X]=160; + thisDetector->nChan[Y]=160; + thisDetector->nChip[X]=1; + thisDetector->nChip[Y]=1; + thisDetector->nDacs=8; + thisDetector->nAdcs=1; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=1; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=16; + break; + case JUNGFRAU: + thisDetector->nChan[X]=256; + thisDetector->nChan[Y]=256; + thisDetector->nChip[X]=4; + thisDetector->nChip[Y]=2; + thisDetector->nDacs=16; + thisDetector->nAdcs=0; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=1; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=16; + break; + case JUNGFRAUCTB: + thisDetector->nChan[X]=32; + thisDetector->nChan[Y]=1; + thisDetector->nChip[X]=1; + thisDetector->nChip[Y]=1; + thisDetector->nDacs=16; + thisDetector->nAdcs=1; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=1; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=16; + break; + case EIGER: + thisDetector->nChan[X]=256; + thisDetector->nChan[Y]=256; + thisDetector->nChip[X]=4; + thisDetector->nChip[Y]=1; + thisDetector->nDacs=16; + thisDetector->nAdcs=0; + thisDetector->nGain=4; + thisDetector->nOffset=4; + thisDetector->nModMax[X]=1; + thisDetector->nModMax[Y]=1; + thisDetector->dynamicRange=16; + break; + default: + thisDetector->nChan[X]=0; + thisDetector->nChan[Y]=0; + thisDetector->nChip[X]=0; + thisDetector->nChip[Y]=0; + thisDetector->nDacs=0; + thisDetector->nAdcs=0; + thisDetector->nGain=0; + thisDetector->nOffset=0; + thisDetector->nModMax[X]=0; + thisDetector->nModMax[Y]=0; + thisDetector->dynamicRange=32; + } + thisDetector->nChans=thisDetector->nChan[X]*thisDetector->nChan[Y]; + thisDetector->nChips=thisDetector->nChip[X]*thisDetector->nChip[Y]; + thisDetector->nModsMax=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; + /** number of modules is initally the maximum number of modules */ + thisDetector->nMod[X]=thisDetector->nModMax[X]; + thisDetector->nMod[Y]=thisDetector->nModMax[Y]; + thisDetector->nMods=thisDetector->nModsMax; + /** calculates the expected data size */ + thisDetector->timerValue[PROBES_NUMBER]=0; + thisDetector->timerValue[FRAME_NUMBER]=1; + thisDetector->timerValue[MEASUREMENTS_NUMBER]=1; + thisDetector->timerValue[CYCLES_NUMBER]=1; + + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*thisDetector->dynamicRange/8; + + if(thisDetector->myDetectorType==JUNGFRAUCTB) { + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->dynamicRange/8; + + } + if(thisDetector->myDetectorType==MYTHEN){ + if (thisDetector->dynamicRange==24 || thisDetector->timerValue[PROBES_NUMBER]>0) + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; + } + + /** set trimDsdir, calDir to default to home directory*/ + strcpy(thisDetector->settingsDir,getenv("HOME")); + strcpy(thisDetector->calDir,getenv("HOME")); + + /** sets trimbit file */ + strcpy(thisDetector->settingsFile,"none"); + /** set progress Index to default to 0*/ + thisDetector->progressIndex=0; + /** set total number of frames to be acquired to default to 1*/ + thisDetector->totalProgress=1; + + /** set trimDsdir, calDir and filePath to default to root directory*/ + strcpy(thisDetector->filePath,"/"); + + /** set number of trim energies to 0*/ + thisDetector->nTrimEn=0; + /** set correction mask to 0*/ + thisDetector->correctionMask=0; + /** set deat time*/ + thisDetector->tDead=0; + /** sets bad channel list file to none */ + strcpy(thisDetector->badChanFile,"none"); + /** sets flat field correction directory */ + strcpy(thisDetector->flatFieldDir,getenv("HOME")); + /** sets flat field correction file */ + strcpy(thisDetector->flatFieldFile,"none"); + /** set number of bad chans to 0*/ + thisDetector->nBadChans=0; + /** set number of bad flat field chans to 0*/ + thisDetector->nBadFF=0; + /** set angular direction to 1*/ + thisDetector->angDirection=1; + /** set fine offset to 0*/ + thisDetector->fineOffset=0; + /** set global offset to 0*/ + thisDetector->globalOffset=0; + /** set number of rois to 0*/ + thisDetector->nROI=0; + /** set readoutflags to none*/ + thisDetector->roFlags=NORMAL_READOUT; + /** set current settings to uninitialized*/ + thisDetector->currentSettings=UNINITIALIZED; + /** set threshold to -1*/ + thisDetector->currentThresholdEV=-1; + // /** set clockdivider to 1*/ + // thisDetector->clkDiv=1; + /** set number of positions to 0*/ + thisDetector->numberOfPositions=0; + /** sets angular conversion file to none */ + strcpy(thisDetector->angConvFile,"none"); + /** set binsize*/ + thisDetector->binSize=0.001; + thisDetector->stoppedFlag=0; + thisDetector->threadedProcessing=1; + + thisDetector->actionMask=0; + + thisDetector->tenGigaEnable=0; + thisDetector->acquiringFlag = false; + + for (int ia=0; iaactionScript[ia],"none"); + strcpy(thisDetector->actionParameter[ia],"none"); + } + + + for (int iscan=0; iscanscanMode[iscan]=0; + strcpy(thisDetector->scanScript[iscan],"none"); + strcpy(thisDetector->scanParameter[iscan],"none"); + thisDetector->nScanSteps[iscan]=0; + thisDetector->scanPrecision[iscan]=0; + } + + /* receiver*/ + /** sets receiver onlineFlag to OFFLINE_FLAG */ + thisDetector->receiverOnlineFlag=OFFLINE_FLAG; + + + /** calculates the memory offsets for flat field coefficients and errors, module structures, dacs, adcs, chips and channels */ + thisDetector->ffoff=sizeof(sharedSlsDetector); + thisDetector->fferroff=thisDetector->ffoff+sizeof(double)*thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax; + thisDetector->modoff= thisDetector->fferroff+sizeof(double)*thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax; + thisDetector->dacoff=thisDetector->modoff+sizeof(sls_detector_module)*thisDetector->nModsMax; + thisDetector->adcoff=thisDetector->dacoff+sizeof(dacs_t)*thisDetector->nDacs*thisDetector->nModsMax; + thisDetector->chipoff=thisDetector->adcoff+sizeof(dacs_t)*thisDetector->nAdcs*thisDetector->nModsMax; + thisDetector->chanoff=thisDetector->chipoff+sizeof(int)*thisDetector->nChips*thisDetector->nModsMax; + thisDetector->gainoff=thisDetector->chanoff+sizeof(int)*thisDetector->nGain*thisDetector->nModsMax; + thisDetector->offsetoff=thisDetector->gainoff+sizeof(int)*thisDetector->nOffset*thisDetector->nModsMax; + + //update?!?!?!? + + + } + + + /** also in case thisDetector alread existed initialize the pointer for flat field coefficients and errors, module structures, dacs, adcs, chips and channels */ + ffcoefficients=(double*)(goff+thisDetector->ffoff); + fferrors=(double*)(goff+thisDetector->fferroff); + detectorModules=(sls_detector_module*)(goff+ thisDetector->modoff); +#ifdef VERBOSE + // for (int imod=0; imod< thisDetector->nModsMax; imod++) + // std::cout<< hex << detectorModules+imod << dec <nBadChans; + badChansList=thisDetector->badChansList; + badChanFile=thisDetector->badChanFile; + nBadFF=&thisDetector->nBadFF; + badFFList=thisDetector->badFFList; + + dacs=(dacs_t*)(goff+thisDetector->dacoff); + adcs=(dacs_t*)(goff+thisDetector->adcoff); + chipregs=(int*)(goff+thisDetector->chipoff); + chanregs=(int*)(goff+thisDetector->chanoff); + gain=(int*)(goff+thisDetector->gainoff); + offset=(int*)(goff+thisDetector->offsetoff); + if (thisDetector->alreadyExisting==0) { + /** if thisDetector is new, initialize its structures \sa initializeDetectorStructure(); */ + initializeDetectorStructure(); + /** set thisDetector->alreadyExisting=1 */ + thisDetector->alreadyExisting=1; + } + +#ifdef VERBOSE + cout << "passing pointers" << endl; +#endif + + + stoppedFlag=&thisDetector->stoppedFlag; + threadedProcessing=&thisDetector->threadedProcessing; + actionMask=&thisDetector->actionMask; + actionScript=thisDetector->actionScript; + actionParameter=thisDetector->actionParameter; + nScanSteps=thisDetector->nScanSteps; + scanMode=thisDetector->scanMode; + scanScript=thisDetector->scanScript; + scanParameter=thisDetector->scanParameter; + scanSteps=thisDetector->scanSteps; + scanPrecision=thisDetector->scanPrecision; + numberOfPositions=&thisDetector->numberOfPositions; + detPositions=thisDetector->detPositions; + angConvFile=thisDetector->angConvFile; + correctionMask=&thisDetector->correctionMask; + binSize=&thisDetector->binSize; + fineOffset=&thisDetector->fineOffset; + globalOffset=&thisDetector->globalOffset; + angDirection=&thisDetector->angDirection; + flatFieldDir=thisDetector->flatFieldDir; + flatFieldFile=thisDetector->flatFieldFile; + badChanFile=thisDetector->badChanFile; + timerValue=thisDetector->timerValue; + expTime=&timerValue[ACQUISITION_TIME]; + + currentSettings=&thisDetector->currentSettings; + currentThresholdEV=&thisDetector->currentThresholdEV; + moveFlag=&thisDetector->moveFlag; + sampleDisplacement=NULL; + settingsFile=thisDetector->settingsFile; + + filePath=thisDetector->filePath; + pthread_mutex_lock(&ms); + fileName=parentDet->fileName; + fileIndex=parentDet->fileIndex; + framesPerFile=parentDet->framesPerFile; + if((thisDetector->myDetectorType==GOTTHARD)||(thisDetector->myDetectorType==PROPIX)) + setFramesPerFile(MAX_FRAMES_PER_FILE); + if (thisDetector->myDetectorType==MOENCH) + setFramesPerFile(MOENCH_MAX_FRAMES_PER_FILE); + if (thisDetector->myDetectorType==JUNGFRAU) + setFramesPerFile(JFRAU_MAX_FRAMES_PER_FILE); + if (thisDetector->myDetectorType==JUNGFRAUCTB) + setFramesPerFile(JFCTB_MAX_FRAMES_PER_FILE); + pthread_mutex_unlock(&ms); + thisReceiver = new receiverInterface(dataSocket); + + // setAngularConversionPointer(thisDetector->angOff,&thisDetector->nMods, thisDetector->nChans*thisDetector->nChips); + +#ifdef VERBOSE + cout << "done" << endl; +#endif + + + /** modifies the last PID accessing the detector */ + thisDetector->lastPID=getpid(); + +#ifdef VERBOSE + cout << "Det size initialized " << endl; +#endif + + return OK; +} + +int slsDetector::initializeDetectorStructure() { + sls_detector_module *thisMod; + char *p2; + p2=(char*)thisDetector; + + /** for each of the detector modules up to the maximum number which can be installed initlialize the sls_detector_module structure \sa ::sls_detector_module*/ + for (int imod=0; imodnModsMax; imod++) { + + + + thisMod=detectorModules+imod; + thisMod->module=imod; + + /** sets the size of the module to nChans, nChips etc. */ + thisMod->nchan=thisDetector->nChans*thisDetector->nChips; + thisMod->nchip=thisDetector->nChips; + thisMod->ndac=thisDetector->nDacs; + thisMod->nadc=thisDetector->nAdcs; + + + /** initializes the serial number and register to 0 */ + thisMod->serialnumber=0; + thisMod->reg=0; + + /** initializes the dacs values to 0 */ + for (int idac=0; idacnDacs; idac++) { + *(dacs+idac+thisDetector->nDacs*imod)=0; + } + + + /** initializes the adc values to 0 */ + for (int iadc=0; iadcnAdcs; iadc++) { + *(adcs+iadc+thisDetector->nAdcs*imod)=0; + } + + + + /** initializes the chip registers to 0 */ + for (int ichip=0; ichipnChips; ichip++) { + *(chipregs+ichip+thisDetector->nChips*imod)=-1; + } + + + /** initializes the channel registers to 0 */ + for (int ichan=0; ichannChans*thisDetector->nChips; ichan++) { + *(chanregs+ichan+thisDetector->nChips*thisDetector->nChans*imod)=-1; + } + + /** initializes the gain values to 0 */ + for (int igain=0; igainnGain; igain++) { + *(gain+igain+thisDetector->nGain*imod)=0; + } + + + /** initializes the offset values to 0 */ + for (int ioffset=0; ioffsetnOffset; ioffset++) { + *(offset+ioffset+thisDetector->nOffset*imod)=0; + } + + /** initialize gain and offset to -1 */ + thisMod->gain=-1.; + thisMod->offset=-1.; + } + return 0; +} + +slsDetectorDefs::sls_detector_module* slsDetector::createModule(detectorType t) { + + sls_detector_module *myMod=(sls_detector_module*)malloc(sizeof(sls_detector_module)); + + + int nch, nm, nc, nd, na=0; + + switch(t) { + case MYTHEN: + nch=128; // complete mythen system + nm=24; + nc=10; + nd=6; // dacs + break; + case PICASSO: + nch=128; // complete mythen system + nm=24; + nc=12; + nd=6; // dacs+adcs + break; + case GOTTHARD: + nch=128; + nm=1; + nc=10; + nd=8; // dacs+adcs + na=5; + break; + case PROPIX: + nch=22*22; + nm=1; + nc=1; + nd=8; // dacs+adcs + na=5; + break; + case EIGER: + nch=256*256; // one EIGER half module + nm=1; //modules/detector + nc=4*1; //chips + nd=16; //dacs + na=0; + break; + case MOENCH: + nch=160*160; + nm=1; //modules/detector + nc=1; //chips + nd=8; //dacs + na=1; + break; + case JUNGFRAU: + nch=256*256;//32; + nm=1; + nc=4*2; + nd=16; // dacs+adcs + na=0; + break; + case JUNGFRAUCTB: + nch=32;//32; + nm=1; + nc=1; + nd=8; // dacs+adcs + na=1; + break; + default: + nch=0; // dum! + nm=0; //modules/detector + nc=0; //chips + nd=0; //dacs+adcs + na=0; + } + + dacs_t *dacs=new dacs_t[nd]; + dacs_t *adcs=new dacs_t[na]; + int *chipregs=new int[nc]; + int *chanregs=new int[nch*nc]; + myMod->ndac=nd; + myMod->nadc=na; + myMod->nchip=nc; + myMod->nchan=nch*nc; + + myMod->dacs=dacs; + myMod->adcs=adcs; + myMod->chipregs=chipregs; + myMod->chanregs=chanregs; + return myMod; +} + + +void slsDetector::deleteModule(sls_detector_module *myMod) { + delete [] myMod->dacs; + delete [] myMod->adcs; + delete [] myMod->chipregs; + delete [] myMod->chanregs; + delete myMod; +} + + + +int slsDetector::sendChannel(sls_detector_channel *myChan) { + int ts=0; + ts+=controlSocket->SendDataOnly(&(myChan->chan),sizeof(myChan->chan)); + ts+=controlSocket->SendDataOnly(&(myChan->chip),sizeof(myChan->chip)); + ts+=controlSocket->SendDataOnly(&(myChan->module),sizeof(myChan->module)); + ts=controlSocket->SendDataOnly(&(myChan->reg),sizeof(myChan->reg)); + return ts; +} + +int slsDetector::sendChip(sls_detector_chip *myChip) { + int ts=0; + //send chip structure + ts+=controlSocket->SendDataOnly(&(myChip->chip),sizeof(myChip->chip)); + ts+=controlSocket->SendDataOnly(&(myChip->module),sizeof(myChip->module)); + ts+=controlSocket->SendDataOnly(&(myChip->nchan),sizeof(myChip->nchan)); + ts+=controlSocket->SendDataOnly(&(myChip->reg),sizeof(myChip->reg)); + ts+=controlSocket->SendDataOnly(myChip->chanregs,sizeof(myChip->chanregs)); +#ifdef VERY_VERBOSE + std::cout<< "chip structure sent" << std::endl; + std::cout<< "now sending " << myChip->nchan << " channles" << std::endl; +#endif + ts=controlSocket->SendDataOnly(myChip->chanregs,sizeof(int)*myChip->nchan ); +#ifdef VERBOSE + std::cout<< "chip's channels sent " <SendDataOnly(&(myMod->module),sizeof(myMod->module)); + ts+=controlSocket->SendDataOnly(&(myMod->serialnumber),sizeof(myMod->serialnumber)); + ts+=controlSocket->SendDataOnly(&(myMod->nchan),sizeof(myMod->nchan)); + ts+=controlSocket->SendDataOnly(&(myMod->nchip),sizeof(myMod->nchip)); + ts+=controlSocket->SendDataOnly(&(myMod->ndac),sizeof(myMod->ndac)); + ts+=controlSocket->SendDataOnly(&(myMod->nadc),sizeof(myMod->nadc)); + ts+=controlSocket->SendDataOnly(&(myMod->reg),sizeof(myMod->reg)); + ts+=controlSocket->SendDataOnly(myMod->dacs,sizeof(myMod->ndac)); + ts+=controlSocket->SendDataOnly(myMod->adcs,sizeof(myMod->nadc)); + + if(thisDetector->myDetectorType != JUNGFRAU){ + ts+=controlSocket->SendDataOnly(myMod->chipregs,sizeof(myMod->nchip)); + ts+=controlSocket->SendDataOnly(myMod->chanregs,sizeof(myMod->nchan)); + } + ts+=controlSocket->SendDataOnly(&(myMod->gain),sizeof(myMod->gain)); + ts+=controlSocket->SendDataOnly(&(myMod->offset), sizeof(myMod->offset)); + ts+=controlSocket->SendDataOnly(myMod->dacs,sizeof(dacs_t)*(myMod->ndac)); + ts+=controlSocket->SendDataOnly(myMod->adcs,sizeof(dacs_t)*(myMod->nadc)); + + if(thisDetector->myDetectorType != JUNGFRAU){ + ts+=controlSocket->SendDataOnly(myMod->chipregs,sizeof(int)*(myMod->nchip)); + ts+=controlSocket->SendDataOnly(myMod->chanregs,sizeof(int)*(myMod->nchan)); + } + return ts; +} + +int slsDetector::receiveChannel(sls_detector_channel *myChan) { + int ts=0; + ts+=controlSocket->ReceiveDataOnly(&(myChan->chan),sizeof(myChan->chan)); + ts+=controlSocket->ReceiveDataOnly(&(myChan->chip),sizeof(myChan->chip)); + ts+=controlSocket->ReceiveDataOnly(&(myChan->module),sizeof(myChan->module)); + ts=controlSocket->ReceiveDataOnly(&(myChan->reg),sizeof(myChan->reg)); + return ts; +} + +int slsDetector::receiveChip(sls_detector_chip* myChip) { + int *ptr=myChip->chanregs; + int nchanold=myChip->nchan; + int ts=0; + int nch; + + //receive chip structure + ts+=controlSocket->ReceiveDataOnly(&(myChip->chip),sizeof(myChip->chip)); + ts+=controlSocket->ReceiveDataOnly(&(myChip->module),sizeof(myChip->module)); + ts+=controlSocket->ReceiveDataOnly(&(myChip->nchan),sizeof(myChip->nchan)); + ts+=controlSocket->ReceiveDataOnly(&(myChip->reg),sizeof(myChip->reg)); + ts+=controlSocket->ReceiveDataOnly(myChip->chanregs,sizeof(myChip->chanregs)); + + myChip->chanregs=ptr; + if (nchanold<(myChip->nchan)) { + nch=nchanold; + printf("number of channels received is too large!\n"); + } else + nch=myChip->nchan; + + ts+=controlSocket->ReceiveDataOnly(myChip->chanregs,sizeof(int)*nch); + + return ts; +} + +int slsDetector::receiveModule(sls_detector_module* myMod) { + + dacs_t *dacptr=myMod->dacs; + dacs_t *adcptr=myMod->adcs; + int *chipptr=myMod->chipregs; + int *chanptr=myMod->chanregs; + int ts=0; + //send module structure + ts+=controlSocket->ReceiveDataOnly(&(myMod->module),sizeof(myMod->module)); + ts+=controlSocket->ReceiveDataOnly(&(myMod->serialnumber),sizeof(myMod->serialnumber)); + ts+=controlSocket->ReceiveDataOnly(&(myMod->nchan),sizeof(myMod->nchan)); + ts+=controlSocket->ReceiveDataOnly(&(myMod->nchip),sizeof(myMod->nchip)); + ts+=controlSocket->ReceiveDataOnly(&(myMod->ndac),sizeof(myMod->ndac)); + ts+=controlSocket->ReceiveDataOnly(&(myMod->nadc),sizeof(myMod->nadc)); + ts+=controlSocket->ReceiveDataOnly(&(myMod->reg),sizeof(myMod->reg)); + ts+=controlSocket->ReceiveDataOnly(myMod->dacs,sizeof(myMod->ndac)); + ts+=controlSocket->ReceiveDataOnly(myMod->adcs,sizeof(myMod->nadc)); + + if(thisDetector->myDetectorType != JUNGFRAU){ + ts+=controlSocket->ReceiveDataOnly(myMod->chipregs,sizeof(myMod->nchip)); + ts+=controlSocket->ReceiveDataOnly(myMod->chanregs,sizeof(myMod->nchan)); + } + ts+=controlSocket->ReceiveDataOnly(&(myMod->gain), sizeof(myMod->gain)); + ts+=controlSocket->ReceiveDataOnly(&(myMod->offset), sizeof(myMod->offset)); + + + myMod->dacs=dacptr; + myMod->adcs=adcptr; + myMod->chipregs=chipptr; + myMod->chanregs=chanptr; + +#ifdef VERBOSE + std::cout<< "received module " << myMod->module << " of size "<< ts << " register " << myMod->reg << std::endl; +#endif + ts+=controlSocket->ReceiveDataOnly(myMod->dacs,sizeof(dacs_t)*(myMod->ndac)); +#ifdef VERBOSE + std::cout<< "received dacs " << myMod->module << " of size "<< ts << std::endl; +#endif + ts+=controlSocket->ReceiveDataOnly(myMod->adcs,sizeof(dacs_t)*(myMod->nadc)); +#ifdef VERBOSE + std::cout<< "received adcs " << myMod->module << " of size "<< ts << std::endl; +#endif + + if(thisDetector->myDetectorType != JUNGFRAU){ + ts+=controlSocket->ReceiveDataOnly(myMod->chipregs,sizeof(int)*(myMod->nchip)); +#ifdef VERBOSE + std::cout<< "received chips " << myMod->module << " of size "<< ts << std::endl; +#endif + ts+=controlSocket->ReceiveDataOnly(myMod->chanregs,sizeof(int)*(myMod->nchan)); +#ifdef VERBOSE + std::cout<< "nchans= " << thisDetector->nChans << " nchips= " << thisDetector->nChips; + std::cout<< "mod - nchans= " << myMod->nchan << " nchips= " <nchip; + std::cout<< "received chans " << myMod->module << " of size "<< ts << std::endl; +#endif + } + +#ifdef VERBOSE + std::cout<< "received module " << myMod->module << " of size "<< ts << " register " << myMod->reg << std::endl; +#endif + + return ts; +} + + +int slsDetector::setOnline(int off) { + int old=thisDetector->onlineFlag; + if (off!=GET_ONLINE_FLAG) { + thisDetector->onlineFlag=off; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + setTCPSocket(); + if (thisDetector->onlineFlag==ONLINE_FLAG && old==OFFLINE_FLAG) { + cout << "Detector connecting for the first time - updating!" << endl; + updateDetector(); + } + else if(thisDetector->onlineFlag==OFFLINE_FLAG){ + std::cout << "cannot connect to detector" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); + } + } + } + return thisDetector->onlineFlag; +} + + + +string slsDetector::checkOnline() { + string retval = string(""); + if(!controlSocket){ + //this already sets the online/offline flag + setTCPSocket(); + if(thisDetector->onlineFlag==OFFLINE_FLAG) + return string(thisDetector->hostname); + else + return string(""); + } + //still cannot connect to socket, controlSocket=0 + if(controlSocket){ + if (connectControl() == FAIL) { + controlSocket->SetTimeOut(5); + thisDetector->onlineFlag=OFFLINE_FLAG; + delete controlSocket; + controlSocket=NULL; + retval = string(thisDetector->hostname); +#ifdef VERBOSE + std::cout<< "offline!" << std::endl; +#endif + } else { + thisDetector->onlineFlag=ONLINE_FLAG; + controlSocket->SetTimeOut(100); + disconnectControl(); +#ifdef VERBOSE + std::cout<< "online!" << std::endl; +#endif + } + } + return retval; +} + + + +int slsDetector::activate(int const enable){ + int fnum = F_ACTIVATE; + int retval = -1; + int arg = enable; + char mess[MAX_STR_LENGTH]=""; + int ret = OK; + + if(thisDetector->myDetectorType != EIGER){ + std::cout<< "Not implemented for this detector" << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE)); + return -1; + } + +#ifdef VERBOSE + if(!enable) + std::cout<< "Deactivating Detector" << std::endl; + else if(enable == -1) + std::cout<< "Getting Detector activate mode" << std::endl; + else + std::cout<< "Activating Detector" << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_ACTIVATE)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + if(retval==1) + std::cout << "Detector Activated" << std::endl; + else if(retval==0) + std::cout << "Detector Deactivated" << std::endl; + else + std::cout << "Detector Activation unknown:" << retval << std::endl; +#endif + + if(ret!=FAIL){ + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Activating/Deactivating Receiver: " << retval << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum,retval,retval); + disconnectData(); + if(ret==FAIL) + setErrorMask((getErrorMask())|(RECEIVER_ACTIVATE)); + } + } +#ifdef VERBOSE + if(retval==1) + std::cout << "Receiver Activated" << std::endl; + else if(retval==0) + std::cout << "Receiver Deactivated" << std::endl; + else + std::cout << "Receiver Activation unknown:" << retval << std::endl; +#endif + + + return retval; + +} + + +/* + configure the socket communication and check that the server exists + enum communicationProtocol{ + TCP, + UDP + }{}; + +*/ + +int slsDetector::setTCPSocket(string const name, int const control_port, int const stop_port){ + + char thisName[MAX_STR_LENGTH]; + int thisCP, thisSP; + int retval=OK; + + if (strcmp(name.c_str(),"")!=0) { +#ifdef VERBOSE + std::cout<< "setting hostname" << std::endl; +#endif + strcpy(thisName,name.c_str()); + strcpy(thisDetector->hostname,thisName); + if (controlSocket) { + delete controlSocket; + controlSocket=NULL; + } + if (stopSocket) { + delete stopSocket; + stopSocket=NULL; + } + } else + strcpy(thisName,thisDetector->hostname); + + if (control_port>0) { +#ifdef VERBOSE + std::cout<< "setting control port" << std::endl; +#endif + thisCP=control_port; + thisDetector->controlPort=thisCP; + if (controlSocket) { + delete controlSocket; + controlSocket=NULL; + } + } else + thisCP=thisDetector->controlPort; + + if (stop_port>0) { +#ifdef VERBOSE + std::cout<< "setting stop port" << std::endl; +#endif + thisSP=stop_port; + thisDetector->stopPort=thisSP; + if (stopSocket) { + delete stopSocket; + stopSocket=NULL; + } + } else + thisSP=thisDetector->stopPort; + + + if (!controlSocket) { + controlSocket= new MySocketTCP(thisName, thisCP); + if (controlSocket->getErrorStatus()){ +#ifdef VERBOSE + std::cout<< "Could not connect Control socket " << thisName << " " << thisCP << std::endl; +#endif + delete controlSocket; + controlSocket=NULL; + retval=FAIL; + } +#ifdef VERYVERBOSE + else + std::cout<< "Control socket connected " <getErrorStatus()){ +#ifdef VERBOSE + std::cout<< "Could not connect Stop socket "<onlineFlag=OFFLINE_FLAG; +#ifdef VERBOSE + std::cout<< "offline!" << std::endl; +#endif + } + return retval; +}; + + +/** connect to the control port */ +int slsDetector::connectControl() { + if (controlSocket){ + if (controlSocket->Connect() >= 0) + return OK; + else{ + std::cout << "cannot connect to detector" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); + return FAIL; + } + } + return UNDEFINED; +} +/** disconnect from the control port */ +int slsDetector::disconnectControl() { + if (controlSocket) + controlSocket->Disconnect(); + return OK; +} + + + +/** connect to the data port */ +int slsDetector::connectData() { + if (dataSocket){ + if (dataSocket->Connect() >= 0) + return OK; + else{ + std::cout << "cannot connect to receiver" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); + return FAIL;} + } + return UNDEFINED; +}; +/** disconnect from the data port */ +int slsDetector::disconnectData(){ + if (dataSocket) + dataSocket->Disconnect(); + return OK; +} +; + +/** connect to the stop port */ +int slsDetector::connectStop() { + if (stopSocket){ + if (stopSocket->Connect() >= 0) + return OK; + else{ + std::cout << "cannot connect to stop server" << endl; + return FAIL; + } + } + return UNDEFINED; +}; +/** disconnect from the stop port */ +int slsDetector::disconnectStop(){ + if (stopSocket) + stopSocket->Disconnect(); + return OK; +} +; + + + + + + + + + + + + + + + + + +/* Communication to server */ + +// General purpose functions + +/* + executes a system command on the server + e.g. mount an nfs disk, reboot and returns answer etc. +*/ +int slsDetector::execCommand(string cmd, string answer){ + + char arg[MAX_STR_LENGTH], retval[MAX_STR_LENGTH]; + int fnum=F_EXEC_COMMAND; + + int ret=FAIL; + + strcpy(arg,cmd.c_str()); + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Sending command " << arg << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + if (controlSocket->SendDataOnly(&fnum,sizeof(fnum))>=0) { + if (controlSocket->SendDataOnly(arg,MAX_STR_LENGTH)>=0) { + if (controlSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH)>=0) { + ret=OK; + answer=retval; + } + } + } + disconnectControl(); + } +#ifdef VERBOSE + std::cout<< "Detector answer is " << answer << std::endl; +#endif + } + return ret; +}; + +// Detector configuration functions + +/* + the detector knows what type of detector it is + + enum detectorType{ + GET_DETECTOR_TYPE, + GENERIC, + MYTHEN, + PILATUS, + EIGER, + GOTTHARD, + AGIPD, + MOENCH + }; + +*/ +int slsDetector::setDetectorType(detectorType const type){ + + int arg, retval=FAIL; + int fnum=F_GET_DETECTOR_TYPE,fnum2=F_GET_RECEIVER_TYPE; + arg=int(type); + detectorType retType=type; + char mess[MAX_STR_LENGTH]=""; + strcpy(mess,"dummy"); + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting detector type to " << arg << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (retval!=FAIL) + controlSocket->ReceiveDataOnly(&retType,sizeof(retType)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (retval==FORCE_UPDATE) + updateDetector(); + } + } else { + if (type==GET_DETECTOR_TYPE) + retType=thisDetector->myDetectorType; + else { + retType=type; + thisDetector->myDetectorType=type; + } + retval=OK; + } +#ifdef VERBOSE + std::cout<< "Detector type set to " << retType << std::endl; +#endif + if (retval==FAIL) { + std::cout<< "Set detector type failed " << std::endl; + retType=GENERIC; + } + else + thisDetector->myDetectorType=retType; + + + //receiver + if((retType != GENERIC) && (setReceiverOnline()==ONLINE_FLAG)) { + retval = FAIL; + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending detector type to Receiver " << (int)thisDetector->myDetectorType << std::endl; +#endif + if (connectData() == OK) + retval=thisReceiver->sendInt(fnum2,arg,(int)thisDetector->myDetectorType); + disconnectData(); + if(retval==FAIL){ + cout << "ERROR: Could not send detector type to receiver" << endl; + setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTTYPE_NOT_SET)); + } + } + } + + + + return retType; +}; + +int slsDetector::setDetectorType(string const stype){ + return setDetectorType(getDetectorType(stype)); +}; + +slsDetectorDefs::detectorType slsDetector::getDetectorsType(int pos){ + return thisDetector->myDetectorType; +} + + + + +/* needed to set/get the size of the detector */ +// if n=GET_FLAG returns the number of installed modules, +int slsDetector::setNumberOfModules(int n, dimension d){ + + int arg[2], retval=1; + int fnum=F_SET_NUMBER_OF_MODULES; + int ret=FAIL; + char mess[MAX_STR_LENGTH]="dummy"; + int connect; + int num; + + arg[0]=d; + arg[1]=n; + + + if (dY) { + std::cout<< "Set number of modules in wrong dimension " << d << std::endl; + return ret; + } + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting number of modules of dimension "<< d << " to " << n << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + connect = connectControl(); + if (connect == UNDEFINED) + cout << "no control socket?" << endl; + else if (connect == OK){ + num = controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + num = controlSocket->SendDataOnly(&arg,sizeof(arg)); + num = controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + num = controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + cout << "offline" << endl; + ret=OK; + if (n==GET_FLAG) + ; + else { + if (n<=0 || n>thisDetector->nModMax[d]) { + ret=FAIL; + } else { + thisDetector->nMod[d]=n; + } + } + retval=thisDetector->nMod[d]; + } +#ifdef VERBOSE + std::cout<< "Number of modules in dimension "<< d <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Set number of modules failed " << std::endl; + } else { + thisDetector->nMod[d]=retval; + thisDetector->nMods=thisDetector->nMod[X]*thisDetector->nMod[Y]; + + + if (thisDetector->nModsMaxnMods) + thisDetector->nModsMax=thisDetector->nMods; + + if (thisDetector->nModMax[X]nMod[X]) + thisDetector->nModMax[X]=thisDetector->nMod[X]; + + if (thisDetector->nModMax[Y]nMod[Y]) + thisDetector->nModMax[Y]=thisDetector->nMod[Y]; + + + + + + + + + + int dr=thisDetector->dynamicRange; + if (dr==24) + dr=32; + + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*dr/8; + + if(thisDetector->myDetectorType==MYTHEN){ + if (thisDetector->timerValue[PROBES_NUMBER]!=0) + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; + } + + if(thisDetector->myDetectorType==JUNGFRAUCTB){ + + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*dr/8; + + } + +#ifdef VERBOSE + std::cout<< "Data size is " << thisDetector->dataBytes << std::endl; + std::cout<< "nModX " << thisDetector->nMod[X] << " nModY " << thisDetector->nMod[Y] << " nChips " << thisDetector->nChips << " nChans " << thisDetector->nChans<< " dr " << dr << std::endl; +#endif + } + + if(n != GET_FLAG){ + pthread_mutex_lock(&ms); + parentDet->updateOffsets(); + pthread_mutex_unlock(&ms); + } + + return thisDetector->nMod[d]; +}; + + + +int slsDetector::getMaxNumberOfModules(dimension d){ + + int retval; + int fnum=F_GET_MAX_NUMBER_OF_MODULES; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + if (dY) { + std::cout<< "Get max number of modules in wrong dimension " << d << std::endl; + return ret; + } +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Getting max number of modules in dimension "<< d <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&d,sizeof(d)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + ret=OK; + retval=thisDetector->nModMax[d]; + } +#ifdef VERBOSE + std::cout<< "Max number of modules in dimension "<< d <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Get max number of modules failed " << retval << std::endl; + return retval; + } else { + thisDetector->nModMax[d]=retval; + thisDetector->nModsMax=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; + + + + } + return thisDetector->nModMax[d]; +}; + + + +/* + This function is used to set the polarity and meaning of the digital I/O signals (signal index) + + enum externalSignalFlag { + GET_EXTERNAL_SIGNAL_FLAG, + SIGNAL_OFF, + GATE_ACTIVE_HIGH, + GATE_ACTIVE_LOW, + TRIGGER_RISING_EDGE, + TRIGGER_FALLING_EDGE + }{}; +*/ + +slsDetectorDefs::externalSignalFlag slsDetector::setExternalSignalFlags(externalSignalFlag pol, int signalindex){ + + + + + int arg[2]; + externalSignalFlag retval; + int ret=FAIL; + int fnum=F_SET_EXTERNAL_SIGNAL_FLAG; + char mess[MAX_STR_LENGTH]=""; + + arg[0]=signalindex; + arg[1]=pol; + + retval=GET_EXTERNAL_SIGNAL_FLAG; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting signal "<< signalindex << " to flag" << pol << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + retval=GET_EXTERNAL_SIGNAL_FLAG; + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Signal "<< signalindex << " flag set to" << retval << std::endl; + if (ret==FAIL) { + std::cout<< "Set signal flag failed " << std::endl; + } +#endif + return retval; + + + + + + +}; + +/* + this function is used to select wether the detector is triggered or gated and in which mode + enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + BURST_TRIGGER, + //GATE_COINCIDENCE_WITH_INTERNAL_ENABLE + }; + +*/ + +slsDetectorDefs::externalCommunicationMode slsDetector::setExternalCommunicationMode( externalCommunicationMode pol){ + + + + + int arg[1]; + externalCommunicationMode retval; + int fnum=F_SET_EXTERNAL_COMMUNICATION_MODE; + char mess[MAX_STR_LENGTH]=""; + + arg[0]=pol; + + int ret=FAIL; + retval=GET_EXTERNAL_COMMUNICATION_MODE; + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting communication to mode " << pol << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + retval=GET_EXTERNAL_COMMUNICATION_MODE; + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Communication mode "<< " set to" << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Setting communication mode failed" << std::endl; + } + return retval; + +}; + + +// Tests and identification +/* + Gets versions + + enum idMode{ + MODULE_SERIAL_NUMBER, + MODULE_FIRMWARE_VERSION, + DETECTOR_SERIAL_NUMBER, + DETECTOR_FIRMWARE_VERSION, + DETECTOR_SOFTWARE_VERSION, + THIS_SOFTWARE_VERSION, + RECEIVER_VERSION + }{}; +*/ + + + + + +int64_t slsDetector::getId( idMode mode, int imod){ + + int64_t retval=-1; + int fnum=F_GET_ID,fnum2 = F_GET_RECEIVER_ID; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< std::endl; + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Getting id of "<< imod << std::endl; + else + std::cout<< "Getting id type "<< mode << std::endl; +#endif + if (mode==THIS_SOFTWARE_VERSION) { + ret=OK; + retval=SVNREVLIB; + retval=(retval<<32) | SVNDATELIB; + } else if (mode==RECEIVER_VERSION) { + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { + if (connectData() == OK) + ret=thisReceiver->getInt(fnum2,retval); + disconnectData(); + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + } else { + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() != OK) + ret = FAIL; + else{ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + if (mode==MODULE_SERIAL_NUMBER) + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + } + if (ret==FAIL) { + std::cout<< "Get id failed " << std::endl; + return ret; + } else { +#ifdef VERBOSE + if (mode==MODULE_SERIAL_NUMBER) + std::cout<< "Id of "<< imod <<" is " << hex <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + if ((mode==CHIP_TEST)|| (mode==DIGITAL_BIT_TEST)) + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + ret=FAIL; + } +#ifdef VERBOSE + std::cout<< "Id "<< mode <<" is " << retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Get id failed " << std::endl; + return ret; + } else + return retval; +}; + + + +/* + analog test of the modules + enum analogTestMode { + COUNT_CALIBRATION_PULSES, + I_DON_T_KNOW + }{}; + +*/ +/* + int* slsDetector::analogTest(analogTestMode mode){ + std::cout<< "function not yet implemented " << std::endl; + }; +*/ +/* + enable analog output of channel +*/ +/* + int slsDetector::enableAnalogOutput(int ichan){ + int imod=ichan/(nChans*nChips); + ichan-=imod*(nChans*nChips); + int ichip=ichan/nChans; + ichan-=ichip*(nChans); + enableAnalogOutput(imod,ichip,ichan); + + }; + int slsDetector::enableAnalogOutput(int imod, int ichip, int ichan){ + std::cout<< "function not yet implemented " << std::endl; + }; +*/ +/* + give a train of calibration pulses +*/ +/* + int slsDetector::giveCalibrationPulse(double vcal, int npulses){ + std::cout<< "function not yet implemented " << std::endl; + }; +*/ +// Expert low level functions + + + +/* write or read register */ + +int slsDetector::writeRegister(int addr, int val){ + + + int retval; + int fnum=F_WRITE_REGISTER; + int ret=FAIL; + + char mess[MAX_STR_LENGTH]=""; + + int arg[2]; + arg[0]=addr; + arg[1]=val; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Writing to register "<< hex<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "Register returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Write to register failed " << std::endl; + } + return retval; + +}; +/* write or read register */ + +int slsDetector::writeAdcRegister(int addr, int val){ + + + int retval; + int fnum=F_WRITE_ADC_REG; + int ret=FAIL; + + char mess[MAX_STR_LENGTH]=""; + + int arg[2]; + arg[0]=addr; + arg[1]=val; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Writing to adc register "<< hex<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "ADC Register returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Write ADC to register failed " << std::endl; + } + return retval; + +}; + + + + +int slsDetector::readRegister(int addr){ + + + int retval; + int fnum=F_READ_REGISTER; + int ret=FAIL; + + char mess[MAX_STR_LENGTH]=""; + + int arg; + arg=addr; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Reading register "<< hex<onlineFlag==ONLINE_FLAG) { + // if (connectControl() == OK){ + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&arg,sizeof(arg)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectStop(); + // if (ret==FORCE_UPDATE) + // updateDetector(); + } + } + } +#ifdef VERBOSE + std::cout<< "Register returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Read register failed " << std::endl; + } + return retval; + +}; + + +// Expert initialization functions +/* + set dacs or read ADC for the module + enum dacIndex { + TRIMBIT_SIZE, + THRESHOLD, + SHAPER1, + SHAPER2, + CALIBRATION_PULSE, + PREAMP, + TEMPERATURE, + HUMIDITY, + }{}; +*/ + +dacs_t slsDetector::setDAC(dacs_t val, dacIndex index, int mV, int imod){ + + + dacs_t retval[2]; + retval[0] = -1; + retval[1] = -1; + int fnum=F_SET_DAC; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + int arg[3]; + + + if ( (thisDetector->myDetectorType == GOTTHARD) || (thisDetector->myDetectorType == PROPIX) && index==HV_NEW) + index=HV_POT; + + arg[0]=index; + arg[1]=imod; + arg[2]=mV; + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Setting DAC "<< index << " of module " << imod << " to " << val << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->SendDataOnly(&val,sizeof(val)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(retval,sizeof(retval)); + if (index < thisDetector->nDacs){ + + if (dacs) { + if (imod>=0) { + *(dacs+index+imod*thisDetector->nDacs)=retval[0]; + } + else { + for (imod=0; imodnModsMax; imod++) + *(dacs+index+imod*thisDetector->nDacs)=retval[0]; + } + } + } + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + + } + } +#ifdef VERBOSE + std::cout<< "Dac set to "<< retval[0] << " dac units (" << retval[1] << "mV)" << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Set dac " << index << " of module " << imod << " to " << val << " failed." << std::endl; + } + if(mV) + return retval[1]; + + return retval[0]; +}; + + +dacs_t slsDetector::getADC(dacIndex index, int imod){ + + dacs_t retval; + int fnum=F_GET_ADC; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + int arg[2]; + arg[0]=index; + arg[1]=imod; + + + +#ifdef VERBOSE + std::cout<< std::endl; + std::cout<< "Getting ADC "<< index << " of module " << imod << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + if (adcs) { + *(adcs+index+imod*thisDetector->nAdcs)=retval; + } + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "ADC returned "<< retval << std::endl; +#endif + if (ret==FAIL) { + std::cout<< "Get ADC failed " << std::endl; + } + + return retval; + + + +}; + +/* + configure single channel + enum channelRegisterBit { + COMPARATOR_ENABLE_OFF, + ANALOG_SIGNAL_ENABLE_OFF, + CALIBRATION_ENABLE_OFF, + TRIMBIT_OFF // should always be the last! + } + +*/ + +int slsDetector::setChannel(int64_t reg, int ichan, int ichip, int imod){ + sls_detector_channel myChan; +#ifdef VERBOSE + std::cout<< "Setting channel "<< ichan << " " << ichip << " " << imod << " to " << reg << std::endl; +#endif + //int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, chamax=ichan+1; + + int ret; + + /* if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + if (ichan==-1) { + chamin=0; + chamax=thisDetector->nChans; + }*/ + + // for (int im=mmin; imonlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendChannel(&chan); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chanregs) { + + int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1, chamin=ichan, chamax=ichan+1; + + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + if (ichan==-1) { + chamin=0; + chamax=thisDetector->nChans; + } + + + + + + + for (int im=mmin; imnChans*thisDetector->nChips+ichi*thisDetector->nChips+icha)=retval; + + } + } + } + + } + } +#ifdef VERBOSE + std::cout<< "Channel register returned "<< retval << std::endl; +#endif + return retval; + +} + + + + + + + + + + + + + + + + + + +slsDetectorDefs::sls_detector_channel slsDetector::getChannel(int ichan, int ichip, int imod){ + + + int fnum=F_GET_CHANNEL; + sls_detector_channel myChan; + int arg[3]; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + arg[0]=ichan; + arg[1]=ichip; + arg[2]=imod; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + receiveChannel(&myChan); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chanregs) { + *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip*thisDetector->nChips+ichan)=myChan.reg; + } + } + +#ifdef VERBOSE + std::cout<< "Returned channel "<< ichan << " " << ichip << " " << imod << " " << myChan.reg << std::endl; +#endif + return myChan; +} + +/* + configure chip + enum chipRegisterBit { + ENABLE_ANALOG_OUTPUT, + OUTPUT_WIDTH // should always be the last + }{}; +*/ +int slsDetector::setChip(int reg, int ichip, int imod){ + sls_detector_chip myChip; + +#ifdef VERBOSE + std::cout<< "Setting chip "<< ichip << " " << imod << " to " << reg << std::endl; +#endif + + + int chregs[thisDetector->nChans]; + int mmin=imod, mmax=imod+1, chimin=ichip, chimax=ichip+1; + int ret=FAIL; + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + if (ichip==-1) { + chimin=0; + chimax=thisDetector->nChips; + } + + myChip.nchan=thisDetector->nChans; + myChip.reg=reg; + for (int im=mmin; imnChans+im*thisDetector->nChans*thisDetector->nChips); + else { + for (int i=0; inChans; i++) + chregs[i]=-1; + myChip.chanregs=chregs; + } + ret=setChip(myChip); + } + } + return ret; +} + +int slsDetector::setChip(sls_detector_chip chip){ + + int fnum=F_SET_CHIP; + int retval; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + int ichi=chip.chip; + int im=chip.module; + + + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendChip(&chip); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chipregs) + *(chipregs+ichi+im*thisDetector->nChips)=retval; + } + +#ifdef VERBOSE + std::cout<< "Chip register returned "<< retval << std::endl; +#endif + return retval; +}; + + +slsDetectorDefs::sls_detector_chip slsDetector::getChip(int ichip, int imod){ + + int fnum=F_GET_CHIP; + sls_detector_chip myChip; + int chanreg[thisDetector->nChans]; + + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + + myChip.chip=ichip; + myChip.module=imod; + myChip.nchan=thisDetector->nChans; + myChip.chanregs=chanreg; + + int arg[2]; + arg[0]=ichip; + arg[1]=imod; + + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + receiveChip(&myChip); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (chipregs) + *(chipregs+ichip+imod*thisDetector->nChips)=myChip.reg; + if (chanregs) { + for (int ichan=0; ichannChans; ichan++) + *(chanregs+imod*thisDetector->nChans*thisDetector->nChips+ichip*thisDetector->nChans+ichan)=*((myChip.chanregs)+ichan); + } + } +#ifdef VERBOSE + std::cout<< "Returned chip "<< ichip << " " << imod << " " << myChip.reg << std::endl; +#endif + + return myChip; +}; + +/* + configure module + enum moduleRegisterBit { + I_DON_T_KNOW, + OUTPUT_WIDTH // should always be the last + }{}; +*/ + +int slsDetector::setModule(int reg, int imod){ + sls_detector_module myModule; + int* g=0; + int* o=0; + int* iod=0; + int64_t tau=-1; + +#ifdef VERBOSE + std::cout << "slsDetector set module " << std::endl; +#endif + int charegs[thisDetector->nChans*thisDetector->nChips]; + int chiregs[thisDetector->nChips]; + dacs_t das[thisDetector->nDacs], ads[thisDetector->nAdcs]; + int mmin=imod, mmax=imod+1; + int ret=FAIL; + + if (imod==-1) { + mmin=0; + mmax=thisDetector->nModsMax; + } + + + + for (int im=mmin; imnChans; + myModule.nchip=thisDetector->nChips; + myModule.ndac=thisDetector->nDacs; + myModule.nadc=thisDetector->nAdcs; + + myModule.reg=reg; + if (detectorModules) { + myModule.gain=(detectorModules+im)->gain; + myModule.offset=(detectorModules+im)->offset; + myModule.serialnumber=(detectorModules+im)->serialnumber; + } else { + myModule.gain=-1; + myModule.offset=-1; + myModule.serialnumber=-1; + } + + + for (int i=0; inAdcs; i++) + ads[i]=-1; + + if (chanregs) + myModule.chanregs=chanregs+im*thisDetector->nChips*thisDetector->nChans; + else { + for (int i=0; inChans*thisDetector->nChips; i++) + charegs[i]=-1; + myModule.chanregs=charegs; + } + if (chipregs) + myModule.chipregs=chanregs+im*thisDetector->nChips; + else { + for (int ichip=0; ichipnChips; ichip++) + chiregs[ichip]=-1; + myModule.chipregs=chiregs; + } + if (dacs) + myModule.dacs=dacs+im*thisDetector->nDacs; + else { + for (int i=0; inDacs; i++) + das[i]=-1; + myModule.dacs=das; + } + if (adcs) + myModule.adcs=adcs+im*thisDetector->nAdcs; + else { + for (int i=0; inAdcs; i++) + ads[i]=-1; + myModule.adcs=ads; + } + ret=setModule(myModule,g,o,iod,tau); + } + return ret; + + +}; + +int slsDetector::setModule(sls_detector_module module, int* gainval, int* offsetval, int* iodelay, int64_t tau){ + + int fnum=F_SET_MODULE; + int retval; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + + int imod=module.module; + + +#ifdef VERBOSE + std::cout << "slsDetector set module " << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + sendModule(&module); + + //extra gain and offset - eiger + if((thisDetector->nGain) && (gainval)) + controlSocket->SendDataOnly(gainval,sizeof(int)*thisDetector->nGain); + if((thisDetector->nOffset) && (offsetval)) + controlSocket->SendDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); + if(thisDetector->myDetectorType == EIGER){ + controlSocket->SendDataOnly(iodelay,sizeof(int)); + controlSocket->SendDataOnly(&tau,sizeof(tau)); + } + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + if(strstr(mess,"default tau")!=NULL) + setErrorMask((getErrorMask())|(RATE_CORRECTION_NO_TAU_PROVIDED)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (detectorModules) { + if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { + (detectorModules+imod)->nchan=module.nchan; + (detectorModules+imod)->nchip=module.nchip; + (detectorModules+imod)->ndac=module.ndac; + (detectorModules+imod)->nadc=module.nadc; + thisDetector->nChips=module.nchip; + thisDetector->nChans=module.nchan/module.nchip; + thisDetector->nDacs=module.ndac; + thisDetector->nAdcs=module.nadc; + + if(thisDetector->myDetectorType != JUNGFRAU){ + for (int ichip=0; ichipnChips; ichip++) { + if (chipregs) + chipregs[ichip+thisDetector->nChips*imod]=module.chipregs[ichip]; + + if (chanregs) { + for (int i=0; inChans; i++) { + chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=module.chanregs[ichip*thisDetector->nChans+i]; + } + } + } + if (adcs) { + for (int i=0; inAdcs; i++) + adcs[i+imod*thisDetector->nAdcs]=module.adcs[i]; + } + } + + if (dacs) { + for (int i=0; inDacs; i++) + dacs[i+imod*thisDetector->nDacs]=module.dacs[i]; + } + + (detectorModules+imod)->gain=module.gain; + (detectorModules+imod)->offset=module.offset; + (detectorModules+imod)->serialnumber=module.serialnumber; + (detectorModules+imod)->reg=module.reg; + } + } + + if ((thisDetector->nGain) && (gainval) && (gain)) { + for (int i=0; inGain; i++) + gain[i+imod*thisDetector->nGain]=gainval[i]; + } + + if ((thisDetector->nOffset) && (offsetval) && (offset)) { + for (int i=0; inOffset; i++) + offset[i+imod*thisDetector->nOffset]=offsetval[i]; + } + + } + +#ifdef VERBOSE + std::cout<< "Module register returned "<< retval << std::endl; +#endif + + return retval; +}; + + + + + +slsDetectorDefs::sls_detector_module *slsDetector::getModule(int imod){ + +#ifdef VERBOSE + std::cout << "slsDetector get module " << std::endl; +#endif + + int fnum=F_GET_MODULE; + sls_detector_module *myMod=createModule(); + + int* gainval=0, *offsetval=0; + if(thisDetector->nGain) + gainval=new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval=new int[thisDetector->nOffset]; + + //char *ptr, *goff=(char*)thisDetector; + + // int chanreg[thisDetector->nChans*thisDetector->nChips]; + //int chipreg[thisDetector->nChips]; + //double dac[thisDetector->nDacs], adc[thisDetector->nAdcs]; + + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + // int n; + +#ifdef VERBOSE + std::cout<< "getting module " << imod << std::endl; +#endif + + myMod->module=imod; + // myMod.nchan=thisDetector->nChans*thisDetector->nChips; + //myMod.chanregs=chanreg; + //myMod.nchip=thisDetector->nChips; + //myMod.chipregs=chipreg; + //myMod.ndac=thisDetector->nDacs; + //myMod.dacs=dac; + //myMod.ndac=thisDetector->nAdcs; + //myMod.dacs=adc; + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + receiveModule(myMod); + + //extra gain and offset - eiger + if(thisDetector->nGain) + controlSocket->ReceiveDataOnly(gainval,sizeof(int)*thisDetector->nGain); + if(thisDetector->nOffset) + controlSocket->ReceiveDataOnly(offsetval,sizeof(int)*thisDetector->nOffset); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if (ret!=FAIL) { + if (detectorModules) { + if (imod>=0 && imodnMod[X]*thisDetector->nMod[Y]) { + (detectorModules+imod)->nchan=myMod->nchan; + (detectorModules+imod)->nchip=myMod->nchip; + (detectorModules+imod)->ndac=myMod->ndac; + (detectorModules+imod)->nadc=myMod->nadc; + thisDetector->nChips=myMod->nchip; + thisDetector->nChans=myMod->nchan/myMod->nchip; + thisDetector->nDacs=myMod->ndac; + thisDetector->nAdcs=myMod->nadc; + + if(thisDetector->myDetectorType != JUNGFRAU){ + for (int ichip=0; ichipnChips; ichip++) { + if (chipregs) + chipregs[ichip+thisDetector->nChips*imod]=myMod->chipregs[ichip]; + + if (chanregs) { + for (int i=0; inChans; i++) { + chanregs[i+ichip*thisDetector->nChans+thisDetector->nChips*thisDetector->nChans*imod]=myMod->chanregs[ichip*thisDetector->nChans+i]; + } + } + } + + if (adcs) { + for (int i=0; inAdcs; i++) + adcs[i+imod*thisDetector->nAdcs]=myMod->adcs[i]; + } + } + + if (dacs) { + for (int i=0; inDacs; i++) + dacs[i+imod*thisDetector->nDacs]=myMod->dacs[i]; + } + (detectorModules+imod)->gain=myMod->gain; + (detectorModules+imod)->offset=myMod->offset; + (detectorModules+imod)->serialnumber=myMod->serialnumber; + (detectorModules+imod)->reg=myMod->reg; + } + } + + if ((thisDetector->nGain) && (gainval) && (gain)) { + for (int i=0; inGain; i++) + gain[i+imod*thisDetector->nGain]=gainval[i]; + } + + if ((thisDetector->nOffset) && (offsetval) && (offset)) { + for (int i=0; inOffset; i++) + offset[i+imod*thisDetector->nOffset]=offsetval[i]; + } + + if(gainval) delete[]gainval; + if(offsetval) delete[]offsetval; + + } else { + deleteModule(myMod); + myMod=NULL; + } + return myMod; +} + + + + +// calibration functions +/* + really needed? + + int slsDetector::setCalibration(int imod, detectorSettings isettings, double gain, double offset){ + std::cout<< "function not yet implemented " << std::endl; + + + + return OK; + + } + int slsDetector::getCalibration(int imod, detectorSettings isettings, double &gain, double &offset){ + + std::cout<< "function not yet implemented " << std::endl; + + + + } +*/ + +/* + calibrated setup of the threshold +*/ + +int slsDetector::getThresholdEnergy(int imod){ + + int fnum= F_GET_THRESHOLD_ENERGY; + int retval; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; +#ifdef VERBOSE + std::cout<< "Getting threshold energy "<< std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + std::cout<< "Detector returned error: "<< std::endl; + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentThresholdEV=retval; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return thisDetector->currentThresholdEV; +}; + +int slsDetector::setThresholdEnergy(int e_eV, int imod, detectorSettings isettings){ + + int fnum= F_SET_THRESHOLD_ENERGY; + int retval; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; +#ifdef VERBOSE + std::cout<< "Setting threshold energy "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&e_eV,sizeof(e_eV)); + controlSocket->SendDataOnly(&imod,sizeof(imod)); + controlSocket->SendDataOnly(&isettings,sizeof(isettings)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + std::cout<< "Detector returned error: "<< std::endl; + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< mess << std::endl; + } else { +#ifdef VERBOSE + std::cout<< "Detector returned OK "<< std::endl; +#endif + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentThresholdEV=retval; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + thisDetector->currentThresholdEV=e_eV; + } + return thisDetector->currentThresholdEV; +}; + +/* + select detector settings +*/ +slsDetectorDefs::detectorSettings slsDetector::getSettings(int imod){ + + + int fnum=F_SET_SETTINGS; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + int retval; + int arg[2]; + arg[0]=GET_SETTINGS; + arg[1]=imod; +#ifdef VERBOSE + std::cout<< "Getting settings "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else{ + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->currentSettings=(detectorSettings)retval; +#ifdef VERBOSE + std::cout<< "Settings are "<< retval << std::endl; +#endif + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return thisDetector->currentSettings; + +}; + + + +slsDetectorDefs::detectorSettings slsDetector::setSettings( detectorSettings isettings, int imod){ +#ifdef VERBOSE + std::cout<< "slsDetector setSettings "<< std::endl; +#endif + sls_detector_module *myMod=createModule(); + int modmi=imod, modma=imod+1, im=imod; + string settingsfname, calfname; + string ssettings; + + int* gainval=0, *offsetval=0; + int* iodelay=0; + if(thisDetector->nGain) + gainval=new int[thisDetector->nGain]; + if(thisDetector->nOffset) + offsetval=new int[thisDetector->nOffset]; + if(thisDetector->myDetectorType == EIGER) + iodelay = new int; + int64_t tau=-1; + + + int ret=0; + + + switch (isettings) { + case STANDARD: + if ( (thisDetector->myDetectorType == MYTHEN) || + (thisDetector->myDetectorType == EIGER)) { + ssettings="/standard"; + thisDetector->currentSettings=STANDARD; + } + break; + case FAST: + if (thisDetector->myDetectorType == MYTHEN) { + ssettings="/fast"; + thisDetector->currentSettings=FAST; + } + break; + case HIGHGAIN: + if ( (thisDetector->myDetectorType == MYTHEN) || + (thisDetector->myDetectorType == GOTTHARD) || + (thisDetector->myDetectorType == PROPIX) || + (thisDetector->myDetectorType == MOENCH) || + (thisDetector->myDetectorType == EIGER)) { + ssettings="/highgain"; + thisDetector->currentSettings=HIGHGAIN; + } + break; + case DYNAMICGAIN: + if ((thisDetector->myDetectorType == GOTTHARD) || + (thisDetector->myDetectorType == PROPIX) || + (thisDetector->myDetectorType == JUNGFRAU) || + (thisDetector->myDetectorType == MOENCH)) { + ssettings="/dynamicgain"; + thisDetector->currentSettings=DYNAMICGAIN; + } + break; + case LOWGAIN: + if ((thisDetector->myDetectorType == GOTTHARD) || + (thisDetector->myDetectorType == PROPIX) || + (thisDetector->myDetectorType == MOENCH) || + (thisDetector->myDetectorType == EIGER) ) { + ssettings="/lowgain"; + thisDetector->currentSettings=LOWGAIN; + } + break; + case MEDIUMGAIN: + if ((thisDetector->myDetectorType == GOTTHARD) || + (thisDetector->myDetectorType == PROPIX) || + (thisDetector->myDetectorType == MOENCH)) { + ssettings="/mediumgain"; + thisDetector->currentSettings=MEDIUMGAIN; + } + break; + case VERYHIGHGAIN: + if ((thisDetector->myDetectorType == GOTTHARD) || + (thisDetector->myDetectorType == PROPIX) || + (thisDetector->myDetectorType == MOENCH)|| + (thisDetector->myDetectorType == EIGER)) { + ssettings="/veryhighgain"; + thisDetector->currentSettings=VERYHIGHGAIN; + } + break; + case LOWNOISE: + break; + case DYNAMICHG0: + if (thisDetector->myDetectorType == JUNGFRAU) { + ssettings="/dynamichg0"; + thisDetector->currentSettings=DYNAMICHG0; + } + break; + case FIXGAIN1: + if (thisDetector->myDetectorType == JUNGFRAU) { + ssettings="/fixgain1"; + thisDetector->currentSettings=FIXGAIN1; + } + break; + case FIXGAIN2: + if (thisDetector->myDetectorType == JUNGFRAU) { + ssettings="/fixgain2"; + thisDetector->currentSettings=FIXGAIN2; + } + break; + case FORCESWITCHG1: + if (thisDetector->myDetectorType == JUNGFRAU) { + ssettings="/forceswitchg1"; + thisDetector->currentSettings=FORCESWITCHG1; + } + break; + case FORCESWITCHG2: + if (thisDetector->myDetectorType == JUNGFRAU) { + ssettings="/forceswitchg2"; + thisDetector->currentSettings=FORCESWITCHG2; + } + break; + case VERYLOWGAIN: + if (thisDetector->myDetectorType == EIGER) { + ssettings="/verylowgain"; + thisDetector->currentSettings=VERYLOWGAIN; + } + break; + default: + break; + } + + + if (isettings != thisDetector->currentSettings) { + std::cout<< "Unknown settings for this detector!" << std::endl; + }else{ + if (imod<0) { + modmi=0; + // modma=thisDetector->nModMax[X]*thisDetector->nModMax[Y]; + modma=thisDetector->nMod[X]*thisDetector->nMod[Y]; + } + + for (im=modmi; immodule=im; + + std::cout << std::endl << "Loading settings for module:" << im << std::endl; + + //create file names + switch(thisDetector->myDetectorType){ + case EIGER: + //settings is saved in myMod.reg + myMod->reg=thisDetector->currentSettings; + ostfn << thisDetector->settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); + oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER) << setbase(10); +#ifdef VERBOSE + std::cout<< thisDetector->settingsDir<calDir <reg=thisDetector->currentSettings; + ostfn << thisDetector->settingsDir << ssettings <<"/settings.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + oscfn << thisDetector->calDir << ssettings << "/calibration.sn";// << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); +#ifdef VERBOSE + std::cout<< thisDetector->settingsDir<calDir <settingsDir << ssettings <<"/noise.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + oscfn << thisDetector->calDir << ssettings << "/calibration.sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im) << setbase(10); + } + + + //settings file**** + settingsfname=ostfn.str(); +#ifdef VERBOSE + cout << "the settings file name is "<myDetectorType, myMod,iodelay)) { + //if it didnt open, try default settings file + ostringstream ostfn_default; + switch(thisDetector->myDetectorType){ + case MOENCH: + case GOTTHARD: + case PROPIX: + case JUNGFRAU: + case JUNGFRAUCTB: + ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".settings"; + break; + case EIGER: + default: + ostfn_default << thisDetector->settingsDir << ssettings << ssettings << ".trim"; + break; + } + settingsfname=ostfn_default.str(); +#ifdef VERBOSE + cout << settingsfname << endl; +#endif + if (!readSettingsFile(settingsfname,thisDetector->myDetectorType, myMod,iodelay)) { + //if default doesnt work, return error + std::cout << "Could not open settings file" << endl; + setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); + return thisDetector->currentSettings; + } + } + + + + //calibration file**** + calfname=oscfn.str(); +#ifdef VERBOSE + cout << "Specific file:"<< calfname << endl; +#endif + //extra gain and offset + if(thisDetector->nGain) + ret = readCalibrationFile(calfname,gainval, offsetval, tau, thisDetector->myDetectorType ); + //normal gain and offset inside sls_detector_module + else + ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); + + //if it didnt open, try default + if(ret != OK){ + ostringstream oscfn_default; + oscfn_default << thisDetector->calDir << ssettings << ssettings << ".cal"; + calfname=oscfn_default.str(); +#ifdef VERBOSE + cout << "Default file:" << calfname << endl; +#endif + //extra gain and offset + if(thisDetector->nGain) + ret = readCalibrationFile(calfname,gainval, offsetval, tau, thisDetector->myDetectorType ); + //normal gain and offset inside sls_detector_module + else + ret = readCalibrationFile(calfname,myMod->gain, myMod->offset); + } + //if default doesnt work, return error + if(ret != OK){ + std::cout << "Could not open calibration file" << calfname << endl; + setErrorMask((getErrorMask())|(SETTINGS_FILE_NOT_OPEN)); + return thisDetector->currentSettings; + } + + //if everything worked, set module**** + setModule(*myMod,gainval,offsetval,iodelay, tau); + } + } + + + + deleteModule(myMod); + if(gainval) delete [] gainval; + if(offsetval) delete [] offsetval; + + switch(thisDetector->myDetectorType==MYTHEN){ + if (thisDetector->correctionMask&(1<-1 && isett<3) { + thisDetector->tDead=t[isett]; + } + } + } + + if (getSettings(imod) != isettings){ + std::cout << "Could not set settings" << endl; + setErrorMask((getErrorMask())|(SETTINGS_NOT_SET)); + } + + return thisDetector->currentSettings; +}; + + + +int slsDetector::getChanRegs(double* retval,bool fromDetector){ + int n=getTotalNumberOfChannels(); + if(fromDetector){ + for(int im=0;imReceiveDataOnly(lastClientIP,sizeof(lastClientIP)); +#ifdef VERBOSE + cout << "Updating detector last modified by " << lastClientIP << std::endl; +#endif + n = controlSocket->ReceiveDataOnly(&nm,sizeof(nm)); + thisDetector->nMod[X]=nm; + n = controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); + /// Should be overcome at a certain point! + + if (thisDetector->myDetectorType==MYTHEN) { + thisDetector->nModMax[X]=nm; + thisDetector->nModMax[Y]=1; + thisDetector->nModsMax=thisDetector->nModMax[Y]*thisDetector->nModMax[X]; + thisDetector->nMod[Y]=1; + } else { + thisDetector->nMod[Y]=nm; + } + + thisDetector->nMods=thisDetector->nMod[Y]*thisDetector->nMod[X]; + if (thisDetector->nModsMaxnMods) + thisDetector->nModsMax=thisDetector->nMods; + + if (thisDetector->nModMax[X]nMod[X]) + thisDetector->nModMax[X]=thisDetector->nMod[X]; + + if (thisDetector->nModMax[Y]nMod[Y]) + thisDetector->nModMax[Y]=thisDetector->nMod[Y]; + + n = controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); + thisDetector->dynamicRange=nm; + + n = controlSocket->ReceiveDataOnly( &nm,sizeof(nm)); + thisDetector->dataBytes=nm; + //t=setSettings(GET_SETTINGS); + n = controlSocket->ReceiveDataOnly( &t,sizeof(t)); + thisDetector->currentSettings=t; + + if((thisDetector->myDetectorType!= GOTTHARD)&& + (thisDetector->myDetectorType!= PROPIX)&& + (thisDetector->myDetectorType!= JUNGFRAU)&& + (thisDetector->myDetectorType!= MOENCH)){ + //thr=getThresholdEnergy(); + n = controlSocket->ReceiveDataOnly( &thr,sizeof(thr)); + thisDetector->currentThresholdEV=thr; + } + + //retval=setFrames(tns); + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[FRAME_NUMBER]=retval; + // retval=setExposureTime(tns); + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[ACQUISITION_TIME]=retval; + + if(thisDetector->myDetectorType == EIGER){ + //retval=setSubFrameExposureTime(tns); + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[SUBFRAME_ACQUISITION_TIME]=retval; + } + //retval=setPeriod(tns); + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[FRAME_PERIOD]=retval; + //retval=setDelay(tns); + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[DELAY_AFTER_TRIGGER]=retval; + // retval=setGates(tns); + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[GATES_NUMBER]=retval; + + //retval=setProbes(tns); + if (thisDetector->myDetectorType == MYTHEN){ + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[PROBES_NUMBER]=retval; + } + + //retval=setTrains(tns); + n = controlSocket->ReceiveDataOnly( &retval,sizeof(int64_t)); + thisDetector->timerValue[CYCLES_NUMBER]=retval; + + return OK; + +} + + + + +int slsDetector::updateDetector() { + int fnum=F_UPDATE_CLIENT; + int ret=OK; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else + updateDetectorNoWait(); + disconnectControl(); + } + } + return ret; +} + + + +// Acquisition functions +/* change these funcs accepting also ok/fail */ + +int slsDetector::startAcquisition(){ + + + int fnum=F_START_ACQUISITION; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Starting acquisition "<< std::endl; +#endif + thisDetector->stoppedFlag=0; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return ret; + + + +}; +int slsDetector::stopAcquisition(){ + + + int fnum=F_STOP_ACQUISITION; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Stopping acquisition "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectStop(); + } + } + } + thisDetector->stoppedFlag=1; + return ret; + + +}; + +int slsDetector::startReadOut(){ + + int fnum=F_START_READOUT; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Starting readout "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return ret; +}; + + +slsDetectorDefs::runStatus slsDetector::getRunStatus(){ + int fnum=F_GET_RUN_STATUS; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + strcpy(mess,"aaaaa"); + runStatus retval=ERROR; +#ifdef VERBOSE + std::cout<< "Getting status "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + + //cout << "________:::____________" << ret << endl; + + if (ret==FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + //cout << "____________________" << retval << endl; + } + disconnectStop(); + } + } + } + return retval; + + +}; + + +int* slsDetector::readFrame(){ + + int fnum=F_READ_FRAME; + int* retval=NULL; + +#ifdef VERBOSE + std::cout<< "slsDetector: Reading frame "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + retval=getDataFromDetector(); + if (retval) { + dataQueue.push(retval); + disconnectControl(); + } + } + } + return retval; +}; + + + + +int* slsDetector::getDataFromDetector(int *retval){ + int nel=thisDetector->dataBytes/sizeof(int); + int n; + + int *r=retval; + + + // int* retval=new int[nel]; + + if (retval==NULL) + retval=new int[nel]; + + int ret=FAIL; + char mess[MAX_STR_LENGTH]="Nothing"; + +#ifdef VERBOSE + std::cout<< "getting data "<< thisDetector->dataBytes << " " << nel<< std::endl; +#endif + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); +#ifdef VERBOSE + cout << "ret=" << ret << endl; +#endif + + if (ret!=OK) { + n= controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + // if(thisDetector->receiverOnlineFlag == OFFLINE_FLAG) + if (ret==FAIL) { + thisDetector->stoppedFlag=1; + std::cout<< "Detector returned: " << mess << " " << n << std::endl; + } else { + ; +#ifdef VERBOSE + std::cout<< "Detector successfully returned: " << mess << " " << n << std::endl; +#endif + } + if (r==NULL) { + delete [] retval; + } + return NULL; + } else { + n=controlSocket->ReceiveDataOnly(retval,thisDetector->dataBytes); + +#ifdef VERBOSE + std::cout<< "Received "<< n << " data bytes" << std::endl; +#endif + if (n!=thisDetector->dataBytes) { + std::cout<< "wrong data size received from detector: received " << n << " but expected " << thisDetector->dataBytes << std::endl; + thisDetector->stoppedFlag=1; + ret=FAIL; + if (r==NULL) { + delete [] retval; + } + return NULL; + } + } + // cout << "get data returning " << endl; + return retval; + +}; + + + + + + +int* slsDetector::readAll(){ + + int fnum=F_READ_ALL; + int* retval; // check what we return! + + int i=0; +#ifdef VERBOSE + std::cout<< "Reading all frames "<< std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + + while ((retval=getDataFromDetector())){ + i++; + //#ifdef VERBOSE + std::cout<< i << std::endl; + //#else + //std::cout << "-" << flush ; + //#endif + dataQueue.push(retval); + std::cout<< "pushed" << std::endl; + } + disconnectControl(); + } + } +#ifdef VERBOSE + std::cout<< "received "<< i<< " frames" << std::endl; + //#else + // std::cout << std::endl; +#endif + return dataQueue.front(); // check what we return! + +}; + + + + + +int slsDetector::readAllNoWait(){ + + int fnum= F_READ_ALL; + +#ifdef VERBOSE + std::cout<< "Reading all frames "<< std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + return OK; + } + } + return FAIL; +}; + + + + + + + + +int* slsDetector::startAndReadAll(){ + + + int* retval; +#ifdef VERBOSE + int i=0; +#endif + startAndReadAllNoWait(); + //#ifdef VERBOSE + // std::cout<< "started" << std::endl; + //#endif + while ((retval=getDataFromDetector())){ +#ifdef VERBOSE + i++; + std::cout<< i << std::endl; + //#else + //std::cout<< "-" << flush; +#endif + dataQueue.push(retval); + } + disconnectControl(); + +#ifdef VERBOSE + std::cout<< "received "<< i<< " frames" << std::endl; + //#else + // std::cout << std::endl; +#endif + return dataQueue.front(); // check what we return! + /* while ((retval=getDataFromDetectorNoWait())) + i++; + #ifdef VERBOSE + std::cout<< "Received " << i << " frames"<< std::endl; + #endif + return dataQueue.front(); // check what we return! + */ + +}; + + + +int slsDetector::startAndReadAllNoWait(){ + + int fnum= F_START_AND_READ_ALL; + +#ifdef VERBOSE + std::cout<< "Starting and reading all frames "<< std::endl; +#endif + thisDetector->stoppedFlag=0; + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + //std::cout<< "connected" << std::endl; + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + return OK; + } + } + return FAIL; +}; + +// int* slsDetector::getDataFromDetectorNoWait() { +// int *retval=getDataFromDetector(); +// if (thisDetector->onlineFlag==ONLINE_FLAG) { +// if (controlSocket) { +// if (retval==NULL){ +// disconnectControl(); + +// #ifdef VERBOSE +// std::cout<< "Run finished "<< std::endl; +// #endif +// } else { +// #ifdef VERBOSE +// std::cout<< "Frame received "<< std::endl; +// #endif +// } +// } +// } +// return retval; // check what we return! +// }; + + + + +/* + set or read the acquisition timers + enum timerIndex { + FRAME_NUMBER, + ACQUISITION_TIME, + FRAME_PERIOD, + DELAY_AFTER_TRIGGER, + GATES_NUMBER, + PROBES_NUMBER + CYCLES_NUMBER, + GATE_INTEGRATED_TIME + } +*/ +int64_t slsDetector::setTimer(timerIndex index, int64_t t){ + + + int fnum=F_SET_TIMER,fnum2=F_SET_RECEIVER_TIMER; + int64_t retval = -1; + int64_t ut = -2; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + int n=0; + + if (index!=MEASUREMENTS_NUMBER) { + + +#ifdef VERBOSE + std::cout<< "Setting timer "<< index << " to " << t << "ns/value" << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&index,sizeof(index)); + n=controlSocket->SendDataOnly(&t,sizeof(t)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_TIMER_VALUE_NOT_SET)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->timerValue[index]=retval; + } + disconnectControl(); + if (ret==FORCE_UPDATE) { + updateDetector(); +#ifdef VERBOSE + std::cout<< "Updated!" << std::endl; +#endif + + } + } + } else { + //std::cout<< "offline " << std::endl; + if (t>=0) + thisDetector->timerValue[index]=t; + if((thisDetector->myDetectorType==GOTTHARD)|| + (thisDetector->myDetectorType==PROPIX)|| + (thisDetector->myDetectorType==JUNGFRAU)|| + (thisDetector->myDetectorType==MOENCH)) + thisDetector->timerValue[PROBES_NUMBER]=0; + } + } else { + if (t>=0) + thisDetector->timerValue[index]=t; + } +#ifdef VERBOSE + std::cout<< "Timer " << index << " set to "<< thisDetector->timerValue[index] << "ns" << std::endl; +#endif + + if ((thisDetector->myDetectorType==MYTHEN)&&(index==PROBES_NUMBER)) { + setDynamicRange(); + //cout << "Changing probes: data size = " << thisDetector->dataBytes <myDetectorType == EIGER) && (t>=0) && getRateCorrection(r)){ + setRateCorrection(r); + } + + //send acquisiton period/frame number to receiver + if((index==FRAME_NUMBER)||(index==FRAME_PERIOD)||(index==CYCLES_NUMBER)){ + if(ret != FAIL){ + retval = thisDetector->timerValue[index]; + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ + int64_t args[2]; + args[1] = retval; + if((t == -1) && (ret!= FORCE_UPDATE)) args[1] = -1; + + if((index==FRAME_NUMBER)||(index==CYCLES_NUMBER)){ +#ifdef VERBOSE + std::cout << "Setting/Getting number of frames " << index <<" to/from receiver " << args[1] << std::endl; +#endif + args[0] = FRAME_NUMBER; + retval = abs(thisDetector->timerValue[FRAME_NUMBER]*thisDetector->timerValue[CYCLES_NUMBER]); + if(args[1] != -1) args[1]=retval; + }else{ +#ifdef VERBOSE + std::cout << "Setting/Getting acquisition period " << index << " to/from receiver " << args[1] << std::endl; +#endif + args[0] = FRAME_PERIOD; + //if acquisition period is zero, then #frames/buffer depends on exposure time and not acq period + if(!retval) args[1] = timerValue[ACQUISITION_TIME]; + } + + + if (connectData() == OK) + ret=thisReceiver->sendIntArray(fnum2,ut,args); + disconnectData(); + if((ut != retval)|| (ret==FAIL)){ + ret = FAIL; + if(index==FRAME_PERIOD){ + //exptime sent if acq period = 0 + if(retval){ + cout << "ERROR:Acquisition Period in receiver set incorrectly to " << ut << " instead of " << thisDetector->timerValue[index] << endl; + setErrorMask((getErrorMask())|(RECEIVER_ACQ_PERIOD_NOT_SET)); + } + }else{ + cout << "ERROR:Number of Frames (* Number of cycles) in receiver set incorrectly to " << ut << " instead of " << thisDetector->timerValue[index] << endl; + setErrorMask((getErrorMask())|(RECEIVER_FRAME_NUM_NOT_SET)); + } + } + + if(ret==FORCE_UPDATE) + updateReceiver(); + } + } + } + return thisDetector->timerValue[index]; +}; + +int slsDetector::lockServer(int lock) { + int fnum=F_LOCK_SERVER; + int retval=-1; + int ret=OK; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&lock,sizeof(lock)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + +} + + +string slsDetector::getLastClientIP() { + + int fnum=F_GET_LAST_CLIENT_IP; + char clientName[INET_ADDRSTRLEN]; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(clientName,sizeof(clientName)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return string(clientName); + +} + + +int slsDetector::setPort(portType index, int num){ + + int fnum=F_SET_PORT, fnum2 = F_SET_RECEIVER_PORT; + int retval; + // uint64_t ut; + char mess[MAX_STR_LENGTH]=""; + int ret=FAIL; + bool online=false; + MySocketTCP *s; + + if (num>1024) { + switch(index) { + case CONTROL_PORT: + s=controlSocket; + retval=thisDetector->controlPort; +#ifdef VERBOSE + cout << "s="<< s<< endl; + cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort << endl; +#endif + if (s==NULL) { + +#ifdef VERBOSE + cout << "s=NULL"<< endl; + cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort << endl; +#endif + setTCPSocket("",DEFAULT_PORTNO); + } + if (controlSocket) { + s=controlSocket; + } else { +#ifdef VERBOSE + cout << "still cannot connect!"<< endl; + cout << thisDetector->controlPort<< " " << " " << thisDetector->stopPort << endl; +#endif + + setTCPSocket("",retval); + } + online = (thisDetector->onlineFlag==ONLINE_FLAG); + + //not an error.could be from config file + if(num==thisDetector->controlPort) + return thisDetector->controlPort; + //reusable port, so print error + else if((num==thisDetector->stopPort)||(num==thisDetector->receiverTCPPort)){ + std::cout<< "Can not connect to port in use " << std::endl; + setErrorMask((getErrorMask())|(COULDNOT_SET_CONTROL_PORT)); + return thisDetector->controlPort; + } + break; + + + case DATA_PORT: + s=dataSocket; + retval=thisDetector->receiverTCPPort; + if(strcmp(thisDetector->receiver_hostname,"none")){ + if (s==NULL) setReceiverTCPSocket("",retval); + if (dataSocket)s=dataSocket; + } + online = (thisDetector->receiverOnlineFlag==ONLINE_FLAG); + + //not an error. could be from config file + if(num==thisDetector->receiverTCPPort) + return thisDetector->receiverTCPPort; + //reusable port, so print error + else if((num==thisDetector->stopPort)||(num==thisDetector->controlPort)){ + std::cout<< "Can not connect to port in use " << std::endl; + setErrorMask((getErrorMask())|(COULDNOT_SET_DATA_PORT)); + return thisDetector->receiverTCPPort; + } + break; + + + case STOP_PORT: + s=stopSocket; + retval=thisDetector->stopPort; + if (s==NULL) setTCPSocket("",-1,DEFAULT_PORTNO+1); + if (stopSocket) s=stopSocket; + else setTCPSocket("",-1,retval); + online = (thisDetector->onlineFlag==ONLINE_FLAG); + + //not an error. could be from config file + if(num==thisDetector->stopPort) + return thisDetector->stopPort; + //reusable port, so print error + else if((num==thisDetector->receiverTCPPort)||(num==thisDetector->controlPort)){ + std::cout<< "Can not connect to port in use " << std::endl; + setErrorMask((getErrorMask())|(COULDNOT_SET_STOP_PORT)); + return thisDetector->stopPort; + } + break; + + default: + s=NULL; + break; + } + + + + + //send to current port to change port + if (online) { + if (s) { + if (s->Connect()>=0) { + if(s==dataSocket) + fnum = fnum2; + s->SendDataOnly(&fnum,sizeof(fnum)); + s->SendDataOnly(&index,sizeof(index)); + s->SendDataOnly(&num,sizeof(num)); + s->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + s->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + s->ReceiveDataOnly(&retval,sizeof(retval)); + } + s->Disconnect(); + }else{ + if (index == CONTROL_PORT){ + std::cout << "cannot connect to detector" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_DETECTOR)); + }else if (index == DATA_PORT){ + std::cout << "cannot connect to receiver" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); + } + } + } + } + + + + if (ret!=FAIL) { + switch(index) { + case CONTROL_PORT: + thisDetector->controlPort=retval; + break; + case DATA_PORT: + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ + thisDetector->receiverTCPPort=retval; + setReceiverOnline(ONLINE_FLAG); + setReceiver(thisDetector->receiver_hostname); + } + break; + case STOP_PORT: + thisDetector->stopPort=retval; + break; + default: + break; + } +#ifdef VERBOSE + cout << "ret is ok" << endl; +#endif + + } else { + switch(index) { + case CONTROL_PORT: + thisDetector->controlPort=num; + setErrorMask((getErrorMask())|(COULDNOT_SET_CONTROL_PORT)); + break; + case DATA_PORT: + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ + thisDetector->receiverTCPPort=retval; + setErrorMask((getErrorMask())|(COULDNOT_SET_DATA_PORT)); + }else{ + thisDetector->receiverTCPPort=num; + if(strcmp(thisDetector->receiver_hostname,"none")) + setReceiver(thisDetector->receiver_hostname); + } + break; + case STOP_PORT: + thisDetector->stopPort=num; + setErrorMask((getErrorMask())|(COULDNOT_SET_STOP_PORT)); + break; + default: + break; + } + } + } + + + + + switch(index) { + case CONTROL_PORT: + retval=thisDetector->controlPort; + break; + case DATA_PORT: + retval=thisDetector->receiverTCPPort; + break; + case STOP_PORT: + retval=thisDetector->stopPort; + break; + default: + retval=-1; + break; + } + + + +#ifdef VERBOSE + cout << thisDetector->controlPort<< " " << thisDetector->receiverTCPPort << " " << thisDetector->stopPort << endl; +#endif + + + + return retval; + +}; + + + + + + + + + + + + +//Naveen change + +int slsDetector::setTotalProgress() { + + int nf=1, npos=1, nscan[MAX_SCAN_LEVELS]={1,1}, nc=1, nm=1; + + if (thisDetector->timerValue[FRAME_NUMBER]) + nf=thisDetector->timerValue[FRAME_NUMBER]; + + if (thisDetector->timerValue[CYCLES_NUMBER]>0) + nc=thisDetector->timerValue[CYCLES_NUMBER]; + + if (thisDetector->numberOfPositions>0) + npos=thisDetector->numberOfPositions; + + if (timerValue[MEASUREMENTS_NUMBER]>0) + nm=timerValue[MEASUREMENTS_NUMBER]; + + + if ((thisDetector->nScanSteps[0]>0) && (thisDetector->actionMask & (1 << MAX_ACTIONS))) + nscan[0]=thisDetector->nScanSteps[0]; + + if ((thisDetector->nScanSteps[1]>0) && (thisDetector->actionMask & (1 << (MAX_ACTIONS+1)))) + nscan[1]=thisDetector->nScanSteps[1]; + + thisDetector->totalProgress=nf*nc*npos*nm*nscan[0]*nscan[1]; + +#ifdef VERBOSE + cout << "nc " << nc << endl; + cout << "nm " << nm << endl; + cout << "nf " << nf << endl; + cout << "npos " << npos << endl; + cout << "nscan[0] " << nscan[0] << endl; + cout << "nscan[1] " << nscan[1] << endl; + + cout << "Set total progress " << thisDetector->totalProgress << endl; +#endif + return thisDetector->totalProgress; +} + + +double slsDetector::getCurrentProgress() { + + return 100.*((double)thisDetector->progressIndex)/((double)thisDetector->totalProgress); +} + + + + + + + + + + + + + + + +/* + important speed parameters + + enum speedVariable { + CLOCK_DIVIDER, + WAIT_STATES, + SET_SIGNAL_LENGTH + }; +*/ + +int slsDetector::setSpeed(speedVariable sp, int value) { + + + int fnum=F_SET_SPEED; + int retval=-1; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + int n=0; +#ifdef VERBOSE + std::cout<< "Setting speed variable"<< sp << " to " << value << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&sp,sizeof(sp)); + n=controlSocket->SendDataOnly(&value,sizeof(value)); +#ifdef VERBOSE + std::cout<< "Sent "<< n << " bytes " << std::endl; +#endif + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_SET_SPEED_PARAMETERS)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "Speed set to "<< retval << std::endl; +#endif + return retval; + +} + + + + +int64_t slsDetector::getTimeLeft(timerIndex index){ + + + int fnum=F_GET_TIME_LEFT; + int64_t retval; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Getting timer "<< index << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (stopSocket) { + if (connectStop() == OK) { + stopSocket->SendDataOnly(&fnum,sizeof(fnum)); + stopSocket->SendDataOnly(&index,sizeof(index)); + stopSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + stopSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + stopSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectStop(); + } + } + } +#ifdef VERBOSE + std::cout<< "Time left is "<< retval << std::endl; +#endif + return retval; + +}; + + +// Flags +int slsDetector::setDynamicRange(int n){ + + // cout << "single " << endl; + int fnum=F_SET_DYNAMIC_RANGE,fnum2=F_SET_RECEIVER_DYNAMIC_RANGE; + int retval=-1,retval1; + char mess[MAX_STR_LENGTH]=""; + int ret=OK, rateret=OK; + +#ifdef VERBOSE + std::cout<< "Setting dynamic range to "<< n << std::endl; +#endif + if (n==24) + n=32; + + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&n,sizeof(n)); + //rate correction is switched off if not 32 bit mode + if(thisDetector->myDetectorType == EIGER){ + controlSocket->ReceiveDataOnly(&rateret,sizeof(rateret)); + if (rateret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + if(strstr(mess,"Rate Correction")!=NULL) + setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32BIT)); + } + } + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else if(thisDetector->myDetectorType==MYTHEN){ + if (n>0) + thisDetector->dynamicRange=n; + retval=thisDetector->dynamicRange; + } + + if (ret!=FAIL && retval>0) { + /* checking the number of probes to chose the data size */ + + + + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*retval/8; + + if (thisDetector->myDetectorType==JUNGFRAUCTB) { + thisDetector->nChip[X]=retval/16; + thisDetector->nChips=thisDetector->nChip[X]*thisDetector->nChip[Y]; + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*retval/8; + } + if(thisDetector->myDetectorType==MYTHEN){ + if (thisDetector->timerValue[PROBES_NUMBER]!=0) + thisDetector->dataBytes=thisDetector->nMod[X]*thisDetector->nMod[Y]*thisDetector->nChips*thisDetector->nChans*4; + + if (retval==32) + thisDetector->dynamicRange=24; + } + + + thisDetector->dynamicRange=retval; + + +#ifdef VERBOSE + std::cout<< "Dynamic range set to "<< thisDetector->dynamicRange << std::endl; + std::cout<< "Data bytes "<< thisDetector->dataBytes << std::endl; +#endif + } + + + //receiver + if(ret != FAIL){ + retval = thisDetector->dynamicRange; + if((n==-1) && (ret!= FORCE_UPDATE)) n =-1; + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending/Getting dynamic range to/from receiver " << n << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum2,retval1,n); + disconnectData(); + if ((ret==FAIL) || (retval1 != retval)){ + ret = FAIL; + cout << "ERROR:Dynamic range in receiver set incorrectly to " << retval1 << " instead of " << retval << endl; + setErrorMask((getErrorMask())|(RECEIVER_DYNAMIC_RANGE)); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + } + + return thisDetector->dynamicRange; +}; + + + + +int slsDetector::setROI(int n,ROI roiLimits[]){ + int ret = FAIL; + //sort ascending order + int temp; + for(int i=0;inROI; + return thisDetector->roiLimits; +} + + +int slsDetector::sendROI(int n,ROI roiLimits[]){ + int ret=FAIL; + int fnum=F_SET_ROI; + char mess[MAX_STR_LENGTH]=""; + int arg = n; + int retvalsize=0; + ROI retval[MAX_ROIS]; + int nrec=-1; + + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + if(arg==-1){; +#ifdef VERBOSE + cout << "Getting ROI from detector" << endl; +#endif + }else{ +#ifdef VERBOSE + cout << "Sending ROI of size " << arg << " to detector" << endl; +#endif + controlSocket->SendDataOnly(roiLimits,arg*sizeof(ROI)); + } + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + + if (ret!=FAIL){ + controlSocket->ReceiveDataOnly(&retvalsize,sizeof(retvalsize)); + nrec = controlSocket->ReceiveDataOnly(retval,retvalsize*sizeof(ROI)); + if(nrec!=(retvalsize*sizeof(ROI))){ + ret=FAIL; + std::cout << " wrong size received: received " << nrec << "but expected " << retvalsize*sizeof(ROI) << endl; + } + }else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + //update client + if(ret!=FAIL){ + for(int i=0;iroiLimits[i]=retval[i]; + thisDetector->nROI = retvalsize; + } + +#ifdef VERBOSE + for(int j=0;jnROI;j++) + cout<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&flag,sizeof(flag)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_SET_READOUT_FLAGS)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->roFlags=retval; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } else { + if (flag!=GET_READOUT_FLAGS) + thisDetector->roFlags=flag; + } + +#ifdef VERBOSE + std::cout<< "Readout flag set to "<< retval << std::endl; +#endif + return thisDetector->roFlags; +}; + +//Trimming +/* + enum trimMode { + NOISE_TRIMMING, + BEAM_TRIMMING, + IMPROVE_TRIMMING, + FIXEDSETTINGS_TRIMMING, + OFFLINE_TRIMMING + }{}; +*/ +int slsDetector::executeTrimming(trimMode mode, int par1, int par2, int imod){ + + int fnum= F_EXECUTE_TRIMMING; + int retval=FAIL; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + int arg[3]; + arg[0]=imod; + arg[1]=par1; + arg[2]=par2; + + +#ifdef VERBOSE + std::cout<< "Trimming module " << imod << " with mode "<< mode << " parameters " << par1 << " " << par2 << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); +#ifdef VERBOSE + std::cout<< "sending mode bytes= "<< controlSocket->SendDataOnly(&mode,sizeof(mode)) << std::endl; +#endif + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { +#ifdef VERBOSE + std::cout<< "Detector trimmed "<< ret << std::endl; +#endif + /* + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + thisDetector->roFlags=retval; + */ + retval=ret; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return retval; + +}; + +double* slsDetector::decodeData(int *datain, double *fdata) { + + double *dataout; + if (fdata) { + dataout=fdata; + // printf("not allocating fdata!\n"); + } + else { + dataout=new double[thisDetector->nChans*thisDetector->nChips*thisDetector->nMods]; + // printf("allocating fdata!\n"); + } + const int bytesize=8; + + int ival=0; + char *ptr=(char*)datain; + char iptr; + + int nbits=thisDetector->dynamicRange; + int nch=thisDetector->nChans*thisDetector->nChips*thisDetector->nMods; + int ipos=0, ichan=0, ibyte; + + if (thisDetector->timerValue[PROBES_NUMBER]==0) { + if (thisDetector->myDetectorType==JUNGFRAUCTB) { + + for (ichan=0; ichandataBytes; ibyte++) { + iptr=ptr[ibyte]&0x1; + for (ipos=0; ipos<8; ipos++) { + // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; + ival=(iptr>>(ipos))&0x1; + dataout[ichan]=ival; + ichan++; + } + } + break; + case 4: + for (ibyte=0; ibytedataBytes; ibyte++) { + iptr=ptr[ibyte]&0xff; + for (ipos=0; ipos<2; ipos++) { + // dataout[ibyte*2+ichan]=((iptr&((0xf)<>ichan)&0xf; + ival=(iptr>>(ipos*4))&0xf; + dataout[ichan]=ival; + ichan++; + } + } + break; + case 8: + for (ichan=0; ichandataBytes; ichan++) { + ival=ptr[ichan]&0xff; + dataout[ichan]=ival; + } + break; + case 16: + for (ichan=0; ichannModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; + //double err[thisDetector->nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; + //double xmed[thisDetector->nModMax[X]*thisDetector->nModMax[Y]*thisDetector->nChans*thisDetector->nChips]; + // int nmed=0; + int im=0; + int nch; + thisDetector->nBadFF=0; + + char ffffname[MAX_STR_LENGTH*2]; + if (fname=="default") { + fname=string(thisDetector->flatFieldFile); + } + + if (fname=="") { +#ifdef VERBOSE + std::cout<< "disabling flat field correction" << std::endl; +#endif + thisDetector->correctionMask&=~(1<flatFieldDir,fname.c_str()); + nch=readDataFile(string(ffffname),data); + if (nch>0) { + + //???? bad ff chans? + int nm=getNMods(); + int chpm[nm]; + int mMask[nm]; + for (int i=0; i=0) { + strcpy(thisDetector->flatFieldFile,fname.c_str()); + + + thisDetector->correctionMask|=(1<correctionMask&(1<nMod[X]*thisDetector->nChans*thisDetector->nChips; ichan++) { + // #ifdef VERBOSE + // std::cout<< ichan << " "<< corr[ichan] << std::endl; + // #endif + ffcoefficients[ichan]=corr[ichan]; + if (ecorr!=NULL) + fferrors[ichan]=ecorr[ichan]; + else + fferrors[ichan]=1; + + cout << ichan << " " << ffcoefficients[ichan] << endl; + } + thisDetector->correctionMask|=(1<correctionMask&=~(1<correctionMask)&(1<correctionMask&(1<correctionMask&(1<nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + // corr[ichan]=(ffcoefficients[ichan]*ffcoefficients[ichan])/(fferrors[ichan]*fferrors[ichan]); + corr[ichan]=ffcoefficients[ichan]; + if (ecorr) { + //ecorr[ichan]=ffcoefficients[ichan]/fferrors[ichan]; + ecorr[ichan]=fferrors[ichan]; + } + } + } + return 1; + } else { +#ifdef VERBOSE + std::cout<< "Flat field correction is disabled" << std::endl; +#endif + if (corr) + for (int ichan=0; ichannMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + corr[ichan]=1; + if (ecorr) + ecorr[ichan]=0; + } + return 0; + } + +} + + +int slsDetector::flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout){ +#ifdef VERBOSE + std::cout<< "Flat field correcting data" << std::endl; +#endif + double e, eo; + if (thisDetector->correctionMask & (1<nMod[X]*thisDetector->nChans*thisDetector->nChips; ichan++) { + if (errin==NULL) { + e=0; + } else { + e=errin[ichan]; + } + postProcessingFuncs::flatFieldCorrect(datain[ichan],e,dataout[ichan],eo,ffcoefficients[ichan],fferrors[ichan]); + if (errout) + errout[ichan]=eo; + // #ifdef VERBOSE + // cout << ichan << " " <SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + if(strstr(mess,"default tau")!=NULL) + setErrorMask((getErrorMask())|(RATE_CORRECTION_NO_TAU_PROVIDED)); + if(strstr(mess,"32")!=NULL) + setErrorMask((getErrorMask())|(RATE_CORRECTION_NOT_32BIT)); + else + setErrorMask((getErrorMask())|(COULD_NOT_SET_RATE_CORRECTION)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + return ret; //only success/fail + } + + + //mythen + double tdead[]=defaultTDead; + if (t==0) { +#ifdef VERBOSE + std::cout<< "unsetting rate correction" << std::endl; +#endif + thisDetector->correctionMask&=~(1<correctionMask|=(1<0) + thisDetector->tDead=t; + else { + if (thisDetector->currentSettings<3 && thisDetector->currentSettings>-1) + thisDetector->tDead=tdead[thisDetector->currentSettings]; + else + thisDetector->tDead=0; + } +#ifdef VERBOSE + std::cout<< "Setting rate correction with dead time "<< thisDetector->tDead << std::endl; +#endif + } + return thisDetector->correctionMask&(1<myDetectorType == EIGER){ + t = getRateCorrectionTau(); + return t; + } + + if (thisDetector->correctionMask&(1<tDead << std::endl; +#endif + t=thisDetector->tDead; + return 1; + } else + t=0; +#ifdef VERBOSE + std::cout<< "Rate correction is disabled " << std::endl; +#endif + return 0; +}; + +double slsDetector::getRateCorrectionTau(){ + + if(thisDetector->myDetectorType == EIGER){ + int fnum=F_GET_RATE_CORRECT; + int ret=FAIL; + char mess[MAX_STR_LENGTH]=""; + int64_t retval = -1; + #ifdef VERBOSE + std::cout<< "Setting Rate Correction to " << arg << endl; + #endif + if (setOnline(ONLINE_FLAG)==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return double(retval); + } + + + //mythen only + if (thisDetector->correctionMask&(1<tDead << std::endl; +#endif + return thisDetector->tDead; + //return 1; + } else +#ifdef VERBOSE + std::cout<< "Rate correction is disabled " << std::endl; +#endif + return 0; +}; + + + + + +int slsDetector::getRateCorrection(){ + + if (thisDetector->myDetectorType == EIGER){ + double t = getRateCorrectionTau(); + return (int)t; + } + + if (thisDetector->correctionMask&(1<tDead; + double t=thisDetector->timerValue[ACQUISITION_TIME]; + // double data; + double e; + if (thisDetector->correctionMask&(1<nMod[X]*thisDetector->nMod[Y]*thisDetector->nChans*thisDetector->nChips; ichan++) { + + if (errin==NULL) { + e=sqrt(datain[ichan]); + } else + e=errin[ichan]; + + postProcessingFuncs::rateCorrect(datain[ichan], e, dataout[ichan], errout[ichan], tau, t); + } + } + + return 0; +}; + + + + + + + +int slsDetector::setBadChannelCorrection(string fname){ + + // int nbadmod; + int ret=0; + //int badchanlist[MAX_BADCHANS]; + //int off; + + string fn=fname; + + if (fname=="default") + fname=string(badChanFile); + + if (nBadChans && badChansList) + ret=setBadChannelCorrection(fname, *nBadChans, badChansList); + + if (ret) { + *correctionMask|=(1<0) { + thisDetector->correctionMask|=(1<nBadChans=0; + for (int ich=0 ;ich=0 && chs[ich]badChansList[ich]=chs[ich]; + thisDetector->nBadChans++; + // cout << "det : " << thisDetector->nBadChans << " " << thisDetector->badChansList[ich] << endl; + } + } + } else + thisDetector->correctionMask&=~(1<0) { + thisDetector->nBadFF=nch; + for (int ich=0 ;ichbadFFList[ich]=chs[ich]; + } + } + } +#ifdef VERBOSE + cout << "badchans flag is "<< (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) << endl; +#endif + // fillBadChannelMask(); + if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + return thisDetector->nBadChans+thisDetector->nBadFF; + } else + return 0; + +} + + + + + + + + +int slsDetector::getBadChannelCorrection(int *bad) { + int ichan; + if (thisDetector->correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + if (bad) { + for (ichan=0; ichannBadChans; ichan++) + bad[ichan]=thisDetector->badChansList[ichan]; + for (int ich=0; ichnBadFF; ich++) + bad[ichan+ich]=thisDetector->badFFList[ich]; + } + return thisDetector->nBadChans+thisDetector->nBadFF; + } else + return 0; +} + + + + + + + + + + +int slsDetector::exitServer(){ + + int retval; + int fnum=F_EXIT_SERVER; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (controlSocket) { + controlSocket->Connect(); + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + } + } + if (retval!=OK) { + std::cout<< std::endl; + std::cout<< "Shutting down the server" << std::endl; + std::cout<< std::endl; + } + return retval; + +}; + + +char* slsDetector::setNetworkParameter(networkParameter index, string value) { + int i; + + switch (index) { + case DETECTOR_MAC: + return setDetectorMAC(value); + case DETECTOR_IP: + return setDetectorIP(value); + case RECEIVER_HOSTNAME: + return setReceiver(value); + case RECEIVER_UDP_IP: + return setReceiverUDPIP(value); + case RECEIVER_UDP_MAC: + return setReceiverUDPMAC(value); + case RECEIVER_UDP_PORT: + sscanf(value.c_str(),"%d",&i); + setReceiverUDPPort(i); + return getReceiverUDPPort(); + case RECEIVER_UDP_PORT2: + sscanf(value.c_str(),"%d",&i); + if(thisDetector->myDetectorType == EIGER) + setReceiverUDPPort2(i); + else + setReceiverUDPPort(i); + if(thisDetector->myDetectorType == EIGER) + return getReceiverUDPPort2(); + return getReceiverUDPPort(); + case DETECTOR_TXN_DELAY_LEFT: + case DETECTOR_TXN_DELAY_RIGHT: + case DETECTOR_TXN_DELAY_FRAME: + case FLOW_CONTROL_10G: + sscanf(value.c_str(),"%d",&i); + return setDetectorNetworkParameter(index, i); + default: + return (char*)("unknown network parameter"); + } + +} + + + +char* slsDetector::getNetworkParameter(networkParameter index) { + + switch (index) { + case DETECTOR_MAC: + return getDetectorMAC(); + break; + case DETECTOR_IP: + return getDetectorIP(); + break; + case RECEIVER_HOSTNAME: + return getReceiver(); + break; + case RECEIVER_UDP_IP: + return getReceiverUDPIP(); + break; + case RECEIVER_UDP_MAC: + return getReceiverUDPMAC(); + break; + case RECEIVER_UDP_PORT: + return getReceiverUDPPort(); + break; + case RECEIVER_UDP_PORT2: + return getReceiverUDPPort2(); + break; + case DETECTOR_TXN_DELAY_LEFT: + case DETECTOR_TXN_DELAY_RIGHT: + case DETECTOR_TXN_DELAY_FRAME: + case FLOW_CONTROL_10G: + return setDetectorNetworkParameter(index, -1); + default: + return (char*)("unknown network parameter"); + } + +} + +char* slsDetector::setDetectorMAC(string detectorMAC){ + if(detectorMAC.length()==17){ + if((detectorMAC[2]==':')&&(detectorMAC[5]==':')&&(detectorMAC[8]==':')&& + (detectorMAC[11]==':')&&(detectorMAC[14]==':')){ + strcpy(thisDetector->detectorMAC,detectorMAC.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) + std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + else if(setUDPConnection()==FAIL) + std::cout<< "Warning: UDP connection set up failed" << std::endl; + }else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: server MAC Address should be in xx:xx:xx:xx:xx:xx format" << endl; + } + } + else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: server MAC Address should be in xx:xx:xx:xx:xx:xx format" << std::endl; + } + + return thisDetector->detectorMAC; +}; + + + +char* slsDetector::setDetectorIP(string detectorIP){ + struct sockaddr_in sa; + //taking function arguments into consideration + if(detectorIP.length()){ + if(detectorIP.length()<16){ + int result = inet_pton(AF_INET, detectorIP.c_str(), &(sa.sin_addr)); + if(result!=0){ + strcpy(thisDetector->detectorIP,detectorIP.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) + std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + else if(setUDPConnection()==FAIL) + std::cout<< "Warning: UDP connection set up failed" << std::endl; + }else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: Detector IP Address should be VALID and in xxx.xxx.xxx.xxx format" << std::endl; + } + } + } + return thisDetector->detectorIP; +} + + + +char* slsDetector::setReceiver(string receiverIP){ + if(getRunStatus()==RUNNING){ + cprintf(RED,"Acquisition already running, Stopping it.\n"); + stopAcquisition(); + } + + strcpy(thisDetector->receiver_hostname,receiverIP.c_str()); + + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Setting up receiver with" << endl; + std::cout << "detector type:" << slsDetectorBase::getDetectorType(thisDetector->myDetectorType) << endl; + std::cout << "detector hostname:" << thisDetector->hostname << endl; + std::cout << "file path:" << fileIO::getFilePath() << endl; + std::cout << "file name:" << fileIO::getFileName() << endl; + std::cout << "file index:" << fileIO::getFileIndex() << endl; + pthread_mutex_lock(&ms); + std::cout << "write enable:" << parentDet->enableWriteToFileMask() << endl; + std::cout << "overwrite enable:" << parentDet->enableOverwriteMask() << endl; + pthread_mutex_unlock(&ms); + std::cout << "frame index needed:" << ((thisDetector->timerValue[FRAME_NUMBER]*thisDetector->timerValue[CYCLES_NUMBER])>1) << endl; + std::cout << "frame period:" << thisDetector->timerValue[FRAME_PERIOD] << endl; + std::cout << "frame number:" << thisDetector->timerValue[FRAME_NUMBER] << endl; + std::cout << "dynamic range:" << thisDetector->dynamicRange << endl << endl; + std::cout << "10GbE:" << thisDetector->tenGigaEnable << endl << endl; +/** enable compresison, */ +#endif + if(setDetectorType()!= GENERIC){ + setDetectorHostname(); + setFilePath(fileIO::getFilePath()); + setFileName(fileIO::getFileName()); + setFileIndex(fileIO::getFileIndex()); + pthread_mutex_lock(&ms); + int imask = parentDet->enableWriteToFileMask(); + pthread_mutex_unlock(&ms); + enableWriteToFile(imask); + pthread_mutex_lock(&ms); + imask = parentDet->enableOverwriteMask(); + pthread_mutex_unlock(&ms); + overwriteFile(imask); + if ((thisDetector->timerValue[FRAME_NUMBER]*thisDetector->timerValue[CYCLES_NUMBER])>1) + setFrameIndex(0); + else + setFrameIndex(-1); + + setTimer(FRAME_PERIOD,thisDetector->timerValue[FRAME_PERIOD]); + setTimer(FRAME_NUMBER,thisDetector->timerValue[FRAME_NUMBER]); + setDynamicRange(thisDetector->dynamicRange); + activate(-1); + //set scan tag + setUDPConnection(); + if(thisDetector->myDetectorType == EIGER) + enableTenGigabitEthernet(thisDetector->tenGigaEnable); + } + } + + return thisDetector->receiver_hostname; +} + + + + +char* slsDetector::setReceiverUDPIP(string udpip){ + struct sockaddr_in sa; + //taking function arguments into consideration + if(udpip.length()){ + if(udpip.length()<16){ + int result = inet_pton(AF_INET, udpip.c_str(), &(sa.sin_addr)); + if(result==0){ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: Receiver UDP IP Address should be VALID and in xxx.xxx.xxx.xxx format" << std::endl; + }else{ + strcpy(thisDetector->receiverUDPIP,udpip.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) + std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + else if(setUDPConnection()==FAIL){ + std::cout<< "Warning: UDP connection set up failed" << std::endl; + } + } + } + } + return thisDetector->receiverUDPIP; +} + + + + +char* slsDetector::setReceiverUDPMAC(string udpmac){ + if(udpmac.length()!=17){ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: receiver udp mac address should be in xx:xx:xx:xx:xx:xx format" << std::endl; + } + else{ + if((udpmac[2]==':')&&(udpmac[5]==':')&&(udpmac[8]==':')&& + (udpmac[11]==':')&&(udpmac[14]==':')){ + strcpy(thisDetector->receiverUDPMAC,udpmac.c_str()); + if(!strcmp(thisDetector->receiver_hostname,"none")) + std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + else if(setUDPConnection()==FAIL){ + std::cout<< "Warning: UDP connection set up failed" << std::endl; + } + }else{ + setErrorMask((getErrorMask())|(COULDNOT_SET_NETWORK_PARAMETER)); + std::cout << "Warning: receiver udp mac address should be in xx:xx:xx:xx:xx:xx format" << std::endl; + } + } + + + return thisDetector->receiverUDPMAC; +} + + + +int slsDetector::setReceiverUDPPort(int udpport){ + thisDetector->receiverUDPPort = udpport; + if(!strcmp(thisDetector->receiver_hostname,"none")) + std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + else if(setUDPConnection()==FAIL){ + std::cout<< "Warning: UDP connection set up failed" << std::endl; + } + return thisDetector->receiverUDPPort; +} + +int slsDetector::setReceiverUDPPort2(int udpport){ + thisDetector->receiverUDPPort2 = udpport; + if(!strcmp(thisDetector->receiver_hostname,"none")) + std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + else if(setUDPConnection()==FAIL){ + std::cout<< "Warning: UDP connection set up failed" << std::endl; + } + return thisDetector->receiverUDPPort2; +} + + +char* slsDetector::setDetectorNetworkParameter(networkParameter index, int delay){ + int fnum = F_SET_NETWORK_PARAMETER; + char* cretval = new char[MAX_STR_LENGTH]; + int ret = FAIL; + int retval = -1; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< "Setting Transmission delay of mode "<< index << " to " << delay << std::endl; +#endif + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&index,sizeof(index)); + controlSocket->SendDataOnly(&delay,sizeof(delay)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_NETWORK_PARAMETER)); + } else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } +#ifdef VERBOSE + std::cout<< "Speed set to "<< retval << std::endl; +#endif + + + sprintf(cretval,"%d",retval); + return cretval; +} + + +int slsDetector::setUDPConnection(){ + + int ret = FAIL; + int fnum = F_SETUP_RECEIVER_UDP; + char args[3][MAX_STR_LENGTH]; + char retval[MAX_STR_LENGTH]=""; + + //called before set up + if(!strcmp(thisDetector->receiver_hostname,"none")){ + std::cout << "Warning: UDP Set up failed. Receiver hostname not set." << endl; + return FAIL; + } + + //if no udp ip given, use hostname + if(!strcmp(thisDetector->receiverUDPIP,"none")){ + //hostname is an ip address + if(strchr(thisDetector->receiver_hostname,'.')!=NULL) + strcpy(thisDetector->receiverUDPIP,thisDetector->receiver_hostname); + //if hostname not ip, convert it to ip + else{ + struct hostent *he = gethostbyname(thisDetector->receiver_hostname); + if (he == NULL){ + cout<<"rx_hostname:"<receiver_hostname<receiverUDPIP,inet_ntoa(*(struct in_addr*)he->h_addr)); + } + } + + + //copy arguments to args[][] + strcpy(args[0],thisDetector->receiverUDPIP); + sprintf(args[1],"%d",thisDetector->receiverUDPPort); + sprintf(args[2],"%d",thisDetector->receiverUDPPort2); +#ifdef VERBOSE + std::cout << "Receiver udp ip address: " << thisDetector->receiverUDPIP << std::endl; + std::cout << "Receiver udp port: " << thisDetector->receiverUDPPort << std::endl; + std::cout << "Receiver udp port2: " << thisDetector->receiverUDPPort2 << std::endl; +#endif + + //set up receiver for UDP Connection and get receivermac address + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Setting up UDP Connection for Receiver " << args[0] << "\t" << args[1] << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendUDPDetails(fnum,retval,args); + disconnectData(); + if(ret!=FAIL){ + strcpy(thisDetector->receiverUDPMAC,retval); + +#ifdef VERBOSE + std::cout << "Receiver mac address: " << thisDetector->receiverUDPMAC << std::endl; +#endif + if(ret==FORCE_UPDATE) + updateReceiver(); + + //configure detector with udp details, -100 is so it doesnt overwrite the previous value + if(configureMAC()==FAIL){ + setReceiverOnline(OFFLINE_FLAG); + std::cout << "could not configure mac" << endl; + } + } + }else + ret=FAIL; + + printReceiverConfiguration(); + + return ret; +} + + + +int slsDetector::configureMAC(){ + int i; + int ret=FAIL; + int fnum=F_CONFIGURE_MAC,fnum2=F_RECEIVER_SHORT_FRAME; + char mess[MAX_STR_LENGTH]=""; + char arg[6][50]; + char cword[50]="", *pcword; + string sword; + int retval=-1; + + + //if udpip wasnt initialized in config file + if(!(strcmp(thisDetector->receiverUDPIP,"none"))){ + //hostname is an ip address + if(strchr(thisDetector->receiver_hostname,'.')!=NULL) + strcpy(thisDetector->receiverUDPIP,thisDetector->receiver_hostname); + //if hostname not ip, convert it to ip + else{ + struct hostent *he = gethostbyname(thisDetector->receiver_hostname); + if (he != NULL) + strcpy(thisDetector->receiverUDPIP,inet_ntoa(*(struct in_addr*)he->h_addr)); + else{ + std::cout << "configure mac failed. no rx_udpip given and invalid receiver hostname" << endl; + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + return FAIL; + } + } + } + strcpy(arg[0],thisDetector->receiverUDPIP); + strcpy(arg[1],thisDetector->receiverUDPMAC); + sprintf(arg[2],"%x",thisDetector->receiverUDPPort); + strcpy(arg[3],thisDetector->detectorMAC); + strcpy(arg[4],thisDetector->detectorIP); + sprintf(arg[5],"%x",thisDetector->receiverUDPPort2); + +#ifdef VERBOSE + std::cout<< "Configuring MAC"<< std::endl; +#endif + + + for(i=0;i<2;i++){ + if(!strcmp(arg[i],"none")){ + std::cout<< "Configure MAC Error. IP/MAC Addresses not set"<< std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + return FAIL; + } + } + +#ifdef VERBOSE + std::cout<< "IP/MAC Addresses valid "<< std::endl; +#endif + + //converting IPaddress to hex. + pcword = strtok (arg[0],"."); + while (pcword != NULL) { + sprintf(arg[0],"%02x",atoi(pcword)); + strcat(cword,arg[0]); + pcword = strtok (NULL, "."); + } + strcpy(arg[0],cword); +#ifdef VERBOSE + std::cout<<"receiver udp ip:"<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + } + else + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + if (ret==FAIL) { + ret=FAIL; + std::cout<< "Configuring MAC failed " << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + } + else if (thisDetector->myDetectorType==GOTTHARD){ + //set frames per file - only for gotthard + pthread_mutex_lock(&ms); + if(retval==-1) + setFramesPerFile(MAX_FRAMES_PER_FILE); + else + setFramesPerFile(SHORT_MAX_FRAMES_PER_FILE); + pthread_mutex_unlock(&ms); + //connect to receiver + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending adc val to receiver " << retval << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum2,retval,retval); + disconnectData(); + if(ret==FAIL) + setErrorMask((getErrorMask())|(COULD_NOT_CONFIGURE_MAC)); + } + } + } + + return ret; +} + + + +//Corrections + + + + + + + +int slsDetector::getAngularConversion(int &direction, angleConversionConstant *angconv) { + direction=thisDetector->angDirection; + if (angconv) { + for (int imod=0; imodnMods; imod++) { + (angconv+imod)->center=thisDetector->angOff[imod].center; + (angconv+imod)->r_conversion=thisDetector->angOff[imod].r_conversion; + (angconv+imod)->offset=thisDetector->angOff[imod].offset; + (angconv+imod)->ecenter=thisDetector->angOff[imod].ecenter; + (angconv+imod)->er_conversion=thisDetector->angOff[imod].er_conversion; + (angconv+imod)->eoffset=thisDetector->angOff[imod].eoffset; + } + } + if (thisDetector->correctionMask&(1<< ANGULAR_CONVERSION)) { + return 1; + } else { + return 0; + } +} + + + +int slsDetector::readAngularConversionFile(string fname) { + + return readAngularConversion(fname,thisDetector->nModsMax, thisDetector->angOff); + +} + +int slsDetector::readAngularConversion(ifstream& ifs) { + + return readAngularConversion(ifs,thisDetector->nModsMax, thisDetector->angOff); + +} + + +int slsDetector:: writeAngularConversion(string fname) { + + return writeAngularConversion(fname, thisDetector->nMods, thisDetector->angOff); + +} + + +int slsDetector:: writeAngularConversion(ofstream &ofs) { + + return writeAngularConversion(ofs, thisDetector->nMods, thisDetector->angOff); + +} + + + + + +int slsDetector::loadImageToDetector(imageType index,string const fname){ + + int ret=FAIL; + short int arg[thisDetector->nChans*thisDetector->nChips]; + +#ifdef VERBOSE + std::cout<< std::endl<< "Loading "; + if(!index) + std::cout<<"Dark"; + else + std::cout<<"Gain"; + std::cout<<" image from file " << fname << std::endl; +#endif + + if(readDataFile(fname,arg)){ + ret = sendImageToDetector(index,arg); + return ret; + } + std::cout<< "Could not open file "<< fname << std::endl; + return ret; +} + + +int slsDetector::sendImageToDetector(imageType index,short int imageVals[]){ + + int ret=FAIL; + int retval; + int fnum=F_LOAD_IMAGE; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Sending image to detector " <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&index,sizeof(index)); + controlSocket->SendDataOnly(imageVals,thisDetector->dataBytes); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} +int slsDetector::getCounterBlock(short int arg[],int startACQ){ + + int ret=FAIL; + int fnum=F_READ_COUNTER_BLOCK; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&startACQ,sizeof(startACQ)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(arg,thisDetector->dataBytes); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + +int slsDetector::writeCounterBlockFile(string const fname,int startACQ){ + + int ret=FAIL; + short int counterVals[thisDetector->nChans*thisDetector->nChips]; + +#ifdef VERBOSE + std::cout<< std::endl<< "Reading Counter to \""<onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&startACQ,sizeof(startACQ)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + +int slsDetector::setCounterBit(int i){ + int fnum=F_SET_COUNTER_BIT; + int ret = FAIL; + int retval=-1; + char mess[MAX_STR_LENGTH]=""; + + if(thisDetector->onlineFlag==ONLINE_FLAG){ +#ifdef VERBOSE + if(i ==-1) + std::cout<< "Getting counter bit from detector" << endl; + else if(i==0) + std::cout<< "Resetting counter bit in detector " << endl; + else + std::cout<< "Setting counter bit in detector " << endl; +#endif + if (connectControl() == OK){ + + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&i,sizeof(i)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_SET_COUNTER_BIT)); + } + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + + } + } + return retval; +} + + + + + + + +int slsDetector::printReceiverConfiguration(){ + + std::cout << "Detector IP:\t\t" << getNetworkParameter(DETECTOR_IP) << std::endl; + std::cout << "Detector MAC:\t\t" << getNetworkParameter(DETECTOR_MAC) << std::endl; + + std::cout << "Receiver Hostname:\t" << getNetworkParameter(RECEIVER_HOSTNAME) << std::endl; + std::cout << "Receiver UDP IP:\t" << getNetworkParameter(RECEIVER_UDP_IP) << std::endl; + std::cout << "Receiver UDP MAC:\t" << getNetworkParameter(RECEIVER_UDP_MAC) << std::endl; + + + std::cout << "Receiver UDP Port:\t" << getNetworkParameter(RECEIVER_UDP_PORT) << std::endl; + if(thisDetector->myDetectorType == EIGER) + std::cout << "Receiver UDP Port2:\t" << getNetworkParameter(RECEIVER_UDP_PORT2) << std::endl; + + std::cout << std::endl; + + return OK; +} + + + +int slsDetector::readConfigurationFile(string const fname){ + + + + string ans; + string str; + ifstream infile; + //char *args[1000]; + + string sargname, sargval; + int iline=0; +#ifdef VERBOSE + std::cout<< "config file name "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + iline=readConfigurationFile(infile); + infile.close(); + } else { + std::cout<< "Error opening configuration file " << fname << " for reading" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Read configuration file of " << iline << " lines" << std::endl; +#endif + return OK; + +} + + +int slsDetector::readConfigurationFile(ifstream &infile){ + + + + + slsDetectorCommand *cmd=new slsDetectorCommand(this); + + string ans; + string str; + int iargval; + int interrupt=0; + char *args[100]; + char myargs[1000][1000]; + + string sargname, sargval; + int iline=0; + while (infile.good() and interrupt==0) { + sargname="none"; + sargval="0"; + getline(infile,str); + iline++; +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + if (str.find('#')!=string::npos) { +#ifdef VERBOSE + std::cout<< "Line is a comment " << std::endl; + std::cout<< str << std::endl; +#endif + continue; + } else if (str.length()<2) { +#ifdef VERBOSE + std::cout<< "Empty line " << std::endl; +#endif + continue; + } else { + istringstream ssstr(str); + iargval=0; + while (ssstr.good()) { + ssstr >> sargname; + //if (ssstr.good()) { +#ifdef VERBOSE + std::cout<< iargval << " " << sargname << std::endl; +#endif + strcpy(myargs[iargval],sargname.c_str()); + args[iargval]=myargs[iargval]; + iargval++; + //} + } + ans=cmd->executeLine(iargval,args,PUT_ACTION); +#ifdef VERBOSE + std::cout<< ans << std::endl; +#endif + } + iline++; + } + delete cmd; + return OK; + +} + + + + + + + + + + +int slsDetector::writeConfigurationFile(string const fname){ + + + ofstream outfile; + int ret; + + outfile.open(fname.c_str(),ios_base::out); + if (outfile.is_open()) { + ret=writeConfigurationFile(outfile); + outfile.close(); + } + else { + std::cout<< "Error opening configuration file " << fname << " for writing" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "wrote " <myDetectorType==GOTTHARD)|| + (thisDetector->myDetectorType==PROPIX)|| + (thisDetector->myDetectorType==JUNGFRAU)|| + (thisDetector->myDetectorType==MOENCH)) { + names[0]= "hostname"; + names[1]= "port"; + names[2]= "stopport"; + names[3]= "settingsdir"; + names[4]= "angdir"; + names[5]= "moveflag"; + names[6]= "lock"; + names[7]= "caldir"; + names[8]= "ffdir"; + names[9]= "extsig"; + names[10]="detectormac"; + names[11]="detectorip"; + names[12]= "rx_tcpport"; + names[13]= "rx_udpport"; + names[14]="rx_udpip"; + names[15]="rx_hostname"; + names[16]="outdir"; + names[17]="vhighvoltage"; + nvar=18; + } + + + int nsig=4;//-1; + int iv=0; + char *args[100]; + char myargs[100][1000]; + + for (int ia=0; ia<100; ia++) { + //args[ia]=new char[1000]; + + args[ia]=myargs[ia]; + } + + + for (iv=0; iv=0) + outfile << id << ":"; + + outfile << args[0] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; + } + } else { + strcpy(args[0],names[iv].c_str()); + if (id>=0) + outfile << id << ":"; + outfile << names[iv] << " " << cmd->executeLine(1,args,GET_ACTION) << std::endl; + } + } + delete cmd; + return OK; +} + + + + + + + + + + + + + + + +int slsDetector::writeSettingsFile(string fname, int imod, int* iodelay){ + + return writeSettingsFile(fname,thisDetector->myDetectorType, detectorModules[imod], iodelay); + +}; + + + + +int slsDetector::loadSettingsFile(string fname, int imod) { + + sls_detector_module *myMod=NULL; + + //tau set to -2 to not affect in any way (-1 for set settings) + int64_t tau =-2; + int* gainval=0; int* offsetval=0; + int *iodelay=0; + if(thisDetector->nGain){ + gainval=new int[thisDetector->nGain]; + for(int i=0;inGain;i++) + gainval[i] = -1; + } + if(thisDetector->nOffset){ + offsetval=new int[thisDetector->nOffset]; + for(int i=0;inOffset;i++) + offsetval[i] = -1; + } + if(thisDetector->myDetectorType == EIGER) + iodelay = new int;*iodelay=0; + string fn=fname; + fn=fname; + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType != EIGER){ + if (fname.find(".sn")==string::npos && fname.find(".trim")==string::npos && fname.find(".settings")==string::npos) { + ostfn << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im); + fn=ostfn.str(); + } + }else if (fname.find(".sn")==string::npos && fname.find(".trim")==string::npos && fname.find(".settings")==string::npos) { + ostfn << ".sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER, im); + fn=ostfn.str(); + } + myMod=readSettingsFile(fn, thisDetector->myDetectorType,myMod,iodelay); + + if (myMod) { + myMod->module=im; + //settings is saved in myMod.reg for all except mythen + if(thisDetector->myDetectorType!=MYTHEN) + myMod->reg=thisDetector->currentSettings; + setModule(*myMod,gainval,offsetval,iodelay,tau); + deleteModule(myMod); + if(gainval) delete[] gainval; + if(offsetval) delete[] offsetval; + } else + return FAIL; + } + return OK; +} + + +int slsDetector::saveSettingsFile(string fname, int imod) { + + sls_detector_module *myMod=NULL; + int ret=FAIL; + int *iod = 0; + + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType == EIGER){ + ostfn << fname << ".sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER); + } else + ostfn << fname << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER,im); + if ((myMod=getModule(im))) { + + if(thisDetector->myDetectorType == EIGER){ + iod = new int; + *iod = (int)setDAC((dacs_t)-1,IO_DELAY,0,-1); + } + ret=writeSettingsFile(ostfn.str(), thisDetector->myDetectorType, *myMod,iod); + deleteModule(myMod); + } + } + return ret; +} + + + +int slsDetector::setAllTrimbits(int val, int imod){ + int fnum=F_SET_ALL_TRIMBITS; + int retval; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting all trimbits to "<< val << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&val,sizeof(val)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(ALLTIMBITS_NOT_SET)); + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + +#ifdef VERBOSE + std::cout<< "All trimbits were set to "<< retval << std::endl; +#endif + return retval; +} + + + + +int slsDetector::loadCalibrationFile(string fname, int imod) { + + sls_detector_module *myMod=NULL; + string fn=fname; + + int64_t tau = -1; + int* gainval=0; int* offsetval=0; + int* iodelay=0; + if(thisDetector->nGain){ + gainval=new int[thisDetector->nGain]; + for(int i=0;inGain;i++) + gainval[i] = -1; + } + if(thisDetector->nOffset){ + offsetval=new int[thisDetector->nOffset]; + for(int i=0;inOffset;i++) + offsetval[i] = -1; + } + + fn=fname; + + + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType != EIGER){ + if (fname.find(".sn")==string::npos && fname.find(".cal")==string::npos) { + ostfn << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER, im); + } + }else if (fname.find(".sn")==string::npos && fname.find(".cal")==string::npos) { + ostfn << "." << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER); + } + fn=ostfn.str(); + if((myMod=getModule(im))){ + iodelay = new int; + *iodelay = (int)setDAC(-1,IO_DELAY,0); + //extra gain and offset + if(thisDetector->nGain){ + if(readCalibrationFile(fn,gainval, offsetval,tau, thisDetector->myDetectorType)==FAIL) + return FAIL; + } //normal gain and offset inside sls_detector_module + else{ + if(readCalibrationFile(fn,myMod->gain, myMod->offset)==FAIL) + return FAIL; + } + setModule(*myMod,gainval,offsetval,iodelay,tau); + + deleteModule(myMod); + if(gainval) delete[]gainval; + if(offsetval) delete[] offsetval; + } else + return FAIL; + } + return OK; +} + + +int slsDetector::saveCalibrationFile(string fname, int imod) { + + + sls_detector_module *myMod=NULL; + int ret=FAIL; + + int mmin=0, mmax=setNumberOfModules(); + if (imod>=0) { + mmin=imod; + mmax=imod+1; + } + for (int im=mmin; immyDetectorType == EIGER) + ostfn << fname << ".sn" << setfill('0') << setw(3) << dec << getId(DETECTOR_SERIAL_NUMBER); + else + ostfn << fname << ".sn" << setfill('0') << setw(3) << hex << getId(MODULE_SERIAL_NUMBER,im); + if ((myMod=getModule(im))) { + //extra gain and offset + if(thisDetector->nGain) + ret=writeCalibrationFile(ostfn.str(),gain, offset,(int64_t)thisDetector->tDead, thisDetector->myDetectorType); + //normal gain and offset inside sls_detector_module + else + ret=writeCalibrationFile(ostfn.str(),myMod->gain, myMod->offset); + + deleteModule(myMod); + }else + return FAIL; + } + return ret; +} + + + + +/* returns if the detector is Master, slave or nothing + \param flag can be GET_MASTER, NO_MASTER, IS_MASTER, IS_SLAVE + \returns master flag of the detector +*/ +slsDetectorDefs::masterFlags slsDetector::setMaster(masterFlags flag) { + + + int fnum=F_SET_MASTER; + masterFlags retval=GET_MASTER; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting master flags to "<< flag << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&flag,sizeof(flag)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + +#ifdef VERBOSE + std::cout<< "Master flag set to "<< retval << std::endl; +#endif + return retval; +} + + + + +/* + Sets/gets the synchronization mode of the various detectors + \param sync syncronization mode can be GET_SYNCHRONIZATION_MODE, NO_SYNCHRONIZATION, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS + \returns current syncronization mode +*/ +slsDetectorDefs::synchronizationMode slsDetector::setSynchronization(synchronizationMode flag) { + + + + int fnum=F_SET_SYNCHRONIZATION_MODE; + synchronizationMode retval=GET_SYNCHRONIZATION_MODE; + char mess[MAX_STR_LENGTH]=""; + int ret=OK; + +#ifdef VERBOSE + std::cout<< "Setting synchronization mode to "<< flag << std::endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&flag,sizeof(flag)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL) { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } else { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + +#ifdef VERBOSE + std::cout<< "Readout flag set to "<< retval << std::endl; +#endif + return retval; + +} + + + + + + + + + + +/*receiver*/ +int slsDetector::setReceiverOnline(int off) { + // int prev = thisDetector->receiverOnlineFlag; + if (off!=GET_ONLINE_FLAG) { + if(strcmp(thisDetector->receiver_hostname,"none")){ + thisDetector->receiverOnlineFlag=off; + if (thisDetector->receiverOnlineFlag==ONLINE_FLAG){ + setReceiverTCPSocket(); + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ + std::cout << "cannot connect to receiver" << endl; + setErrorMask((getErrorMask())|(CANNOT_CONNECT_TO_RECEIVER)); + } + } + } + } + return thisDetector->receiverOnlineFlag; +} + + + +string slsDetector::checkReceiverOnline() { + string retval = ""; + //if it doesnt exits, create data socket + if(!dataSocket){ + //this already sets the online/offline flag + setReceiverTCPSocket(); + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG) + return string(thisDetector->receiver_hostname); + else + return string(""); + } + //still cannot connect to socket, dataSocket=0 + if(dataSocket){ + if (connectData() == FAIL) { + dataSocket->SetTimeOut(5); + thisDetector->receiverOnlineFlag=OFFLINE_FLAG; + delete dataSocket; + dataSocket=NULL; + retval = FAIL; +#ifdef VERBOSE + std::cout<< "receiver offline!" << std::endl; +#endif + } else { + thisDetector->receiverOnlineFlag=ONLINE_FLAG; + dataSocket->SetTimeOut(100); + disconnectData(); +#ifdef VERBOSE + std::cout<< "receiver online!" << std::endl; +#endif + } + } + return retval; +} + + + + + +int slsDetector::setReceiverTCPSocket(string const name, int const receiver_port){ + + char thisName[MAX_STR_LENGTH]; + int thisRP; + int retval=OK; + + //if receiver ip given + if (strcmp(name.c_str(),"")!=0) { +#ifdef VERBOSE + std::cout<< "setting receiver" << std::endl; +#endif + strcpy(thisName,name.c_str()); + strcpy(thisDetector->receiver_hostname,thisName); + if (dataSocket){ + delete dataSocket; + dataSocket=NULL; + } + } else + strcpy(thisName,thisDetector->receiver_hostname); + + //if receiverTCPPort given + if (receiver_port>0) { +#ifdef VERBOSE + std::cout<< "setting data port" << std::endl; +#endif + thisRP=receiver_port; + thisDetector->receiverTCPPort=thisRP; + if (dataSocket){ + delete dataSocket; + dataSocket=NULL; + } + } else + thisRP=thisDetector->receiverTCPPort; + + //create data socket + if (!dataSocket) { + dataSocket=new MySocketTCP(thisName, thisRP); + if (dataSocket->getErrorStatus()){ +#ifdef VERBOSE + std::cout<< "Could not connect Data socket "<receiverOnlineFlag=OFFLINE_FLAG; +#ifdef VERBOSE + std::cout<< "offline!" << std::endl; +#endif + } + thisReceiver->setSocket(dataSocket); + return retval; +}; + + + + + + +string slsDetector::setFilePath(string s) { + int fnum = F_SET_RECEIVER_FILE_PATH; + int ret = FAIL; + char arg[MAX_STR_LENGTH]; + char retval[MAX_STR_LENGTH] = ""; + struct stat st; + + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ + if(!s.empty()){ + if(stat(s.c_str(),&st)){ + std::cout << "path does not exist" << endl; + setErrorMask((getErrorMask())|(FILE_PATH_DOES_NOT_EXIST)); + }else + fileIO::setFilePath(s); + } + } + + else if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ + strcpy(arg,s.c_str()); +#ifdef VERBOSE + std::cout << "Sending file path to receiver " << arg << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendString(fnum,retval,arg); + disconnectData(); + if(ret!=FAIL) + fileIO::setFilePath(string(retval)); + else if(!s.empty()){ + std::cout << "path does not exist" << endl; + setErrorMask((getErrorMask())|(FILE_PATH_DOES_NOT_EXIST)); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return fileIO::getFilePath(); +} + + + +string slsDetector::setFileName(string s) { + int fnum=F_SET_RECEIVER_FILE_NAME; + int ret = FAIL; + char arg[MAX_STR_LENGTH]; + char retval[MAX_STR_LENGTH]=""; + + if(!s.empty()){ + pthread_mutex_lock(&ms); + fileIO::setFileName(s); + if(thisDetector->myDetectorType == EIGER) + parentDet->setDetectorIndex(detId); + else if(parentDet->getNumberOfDetectors()>1) + parentDet->setDetectorIndex(detId); + s=parentDet->createReceiverFilePrefix(); + pthread_mutex_unlock(&ms); + } + + if(thisDetector->receiverOnlineFlag==ONLINE_FLAG){ + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ + strcpy(arg,s.c_str()); +#ifdef VERBOSE + std::cout << "Sending file name to receiver " << arg << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendString(fnum,retval,arg); + disconnectData(); + if(ret!=FAIL){ +#ifdef VERBOSE + std::cout << "Complete file prefix from receiver: " << retval << std::endl; +#endif + pthread_mutex_lock(&ms); + fileIO::setFileName(parentDet->getNameFromReceiverFilePrefix(string(retval))); + pthread_mutex_unlock(&ms); + + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + } + + return fileIO::getFileName(); +} + + + + + +int slsDetector::setFileIndex(int i) { + int fnum=F_SET_RECEIVER_FILE_INDEX; + int ret = FAIL; + int retval=-1; + int arg = i; + + + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ + if(i>=0){ + pthread_mutex_lock(&ms); + fileIO::setFileIndex(i); + pthread_mutex_unlock(&ms); + } + } + + else if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending file index to receiver " << arg << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + if(ret!=FAIL){ + pthread_mutex_lock(&ms); + fileIO::setFileIndex(retval); + pthread_mutex_unlock(&ms); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return fileIO::getFileIndex(); +} + + + + +int slsDetector::startReceiver(){ + int fnum=F_START_RECEIVER; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = ""; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Starting Receiver " << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->executeFunction(fnum,mess); + disconnectData(); + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + else if (ret == FAIL){ + if(strstr(mess,"UDP")!=NULL) + setErrorMask((getErrorMask())|(COULDNOT_CREATE_UDP_SOCKET)); + else if(strstr(mess,"file")!=NULL) + setErrorMask((getErrorMask())|(COULDNOT_CREATE_FILE)); + else + setErrorMask((getErrorMask())|(COULDNOT_START_RECEIVER)); + } + } + //let detector prepare anyway even if receiver didnt work + if((thisDetector->myDetectorType != JUNGFRAU)) + ret=detectorSendToReceiver(true); + + return ret; +} + + + + +int slsDetector::stopReceiver(){ + int fnum=F_STOP_RECEIVER; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = ""; + + if(thisDetector->myDetectorType != EIGER && thisDetector->myDetectorType != JUNGFRAU) + detectorSendToReceiver(false); + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Stopping Receiver " << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->executeFunction(fnum,mess); + disconnectData(); + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + else if (ret == FAIL) + setErrorMask((getErrorMask())|(COULDNOT_STOP_RECEIVER)); + } + + return ret; +} + + + + +slsDetectorDefs::runStatus slsDetector::startReceiverReadout(){ + int fnum=F_START_RECEIVER_READOUT; + int ret = FAIL; + int retval=-1; + runStatus s=ERROR; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Starting Receiver Readout" << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->getInt(fnum,retval); + disconnectData(); + if(retval!=-1) + s=(runStatus)retval; + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + + return s; +} + + +int slsDetector::detectorSendToReceiver(bool set){ + int fnum; + if(set) fnum=F_START_RECEIVER; + else fnum=F_STOP_RECEIVER; + int ret = FAIL; + char mess[MAX_STR_LENGTH]=""; + + if (thisDetector->onlineFlag==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Setting detector to send packets via client to: " << set << std::endl; +#endif + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + }else + std::cout << "cannot connect to detector" << endl; + + return ret; +} + + + + + + + +slsDetectorDefs::runStatus slsDetector::getReceiverStatus(){ + int fnum=F_GET_RECEIVER_STATUS; + int ret = FAIL; + int retval=-1; + runStatus s=ERROR; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Getting Receiver Status" << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->getInt(fnum,retval); + disconnectData(); + if(retval!=-1) + s=(runStatus)retval; + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + + return s; +} + + + + +int slsDetector::getFramesCaughtByReceiver(){ + int fnum=F_GET_RECEIVER_FRAMES_CAUGHT; + int ret = FAIL; + int retval=-1; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Getting Frames Caught by Receiver " << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->getInt(fnum,retval); + disconnectData(); + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + + return retval; +} + + + +int slsDetector::getReceiverCurrentFrameIndex(){ + int fnum=F_GET_RECEIVER_FRAME_INDEX; + int ret = FAIL; + int retval=-1; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Getting Current Frame Index of Receiver " << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->getInt(fnum,retval); + disconnectData(); + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + + return retval; +} + + + + +int slsDetector::resetFramesCaught(){ + int fnum=F_RESET_RECEIVER_FRAMES_CAUGHT; + int ret = FAIL; + char mess[MAX_STR_LENGTH] = ""; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout << "Reset Frames Caught by Receiver" << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->executeFunction(fnum,mess); + disconnectData(); + if(ret==FORCE_UPDATE) + ret=updateReceiver(); + } + + return ret; +} + + + + + +int* slsDetector::readFrameFromReceiver(char* fName, int &acquisitionIndex, int &frameIndex, int &subFrameIndex){ + int fnum=F_READ_RECEIVER_FRAME; + int nel=thisDetector->dataBytes/sizeof(int); + int* retval=new int[nel]; + int ret=FAIL; + int n; + char mess[MAX_STR_LENGTH]="Nothing"; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { +#ifdef VERBOSE + std::cout<< "slsDetector: Reading frame from receiver "<< thisDetector->dataBytes << " " <SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + + if (ret==FAIL) { + n= dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned: " << mess << " " << n << std::endl; + delete [] retval; + disconnectData(); + return NULL; + } else { + n=dataSocket->ReceiveDataOnly(fName,MAX_STR_LENGTH); + n=dataSocket->ReceiveDataOnly(&acquisitionIndex,sizeof(acquisitionIndex)); + n=dataSocket->ReceiveDataOnly(&frameIndex,sizeof(frameIndex)); + if(thisDetector->myDetectorType == EIGER) + n=dataSocket->ReceiveDataOnly(&subFrameIndex,sizeof(subFrameIndex)); + n=dataSocket->ReceiveDataOnly(retval,thisDetector->dataBytes); + +#ifdef VERBOSE + std::cout<< "Received "<< n << " data bytes" << std::endl; +#endif + if (n!=thisDetector->dataBytes) { + std::cout<dataBytes << std::endl; + ret=FAIL; + delete [] retval; + disconnectData(); + return NULL; + } + + //jungfrau masking adcval + if(thisDetector->myDetectorType == JUNGFRAU){ + for(unsigned int i=0;isendInt(fnum,retval,arg); + disconnectData(); + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return retval; +} + + + + + + +string slsDetector::getReceiverLastClientIP(){ + int fnum=F_GET_LAST_RECEIVER_CLIENT_IP; + int ret = FAIL; + char retval[INET_ADDRSTRLEN]=""; + + if(setReceiverOnline(ONLINE_FLAG)!=ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Geting Last Client IP connected to Receiver " << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->getLastClientIP(fnum,retval); + disconnectData(); + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return string(retval); +} + + + + + +int slsDetector::updateReceiverNoWait() { + + int n,ind; + char path[MAX_STR_LENGTH]; + char lastClientIP[INET_ADDRSTRLEN]; + + n = dataSocket->ReceiveDataOnly(lastClientIP,sizeof(lastClientIP)); +#ifdef VERBOSE + cout << "Updating receiver last modified by " << lastClientIP << std::endl; +#endif + n = dataSocket->ReceiveDataOnly(&ind,sizeof(ind)); + pthread_mutex_lock(&ms); + fileIO::setFileIndex(ind); + pthread_mutex_unlock(&ms); + n = dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); + fileIO::setFilePath(path); + n = dataSocket->ReceiveDataOnly(path,MAX_STR_LENGTH); + pthread_mutex_lock(&ms); + fileIO::setFileName(path); + pthread_mutex_unlock(&ms); + return OK; + +} + + + + + +int slsDetector::updateReceiver() { + int fnum=F_UPDATE_RECEIVER_CLIENT; + int ret=OK; + char mess[MAX_STR_LENGTH]=""; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { + if (connectData() == OK){ + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + updateReceiverNoWait(); + else{ + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + disconnectData(); + } + } + + return ret; +} + + + + + + +int slsDetector::exitReceiver(){ + + int retval; + int fnum=F_EXIT_RECEIVER; + + if (setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG) { + if (dataSocket) { + dataSocket->Connect(); + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectData(); + } + } + if (retval!=OK) { + std::cout<< std::endl; + std::cout<< "Shutting down the receiver" << std::endl; + std::cout<< std::endl; + } + return retval; + +} + + + + + +int slsDetector::enableWriteToFile(int enable){ + int fnum=F_ENABLE_RECEIVER_FILE_WRITE; + int ret = FAIL; + int retval=-1; + int arg = enable; + + + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ + if(enable>=0){ + pthread_mutex_lock(&ms); + parentDet->enableWriteToFileMask(enable); + pthread_mutex_unlock(&ms); + } + } + + else if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending enable file write to receiver " << arg << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + if(ret!=FAIL){ + pthread_mutex_lock(&ms); + parentDet->enableWriteToFileMask(retval); + pthread_mutex_unlock(&ms); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + pthread_mutex_lock(&ms); + retval = parentDet->enableWriteToFileMask(); + pthread_mutex_unlock(&ms); + + return retval; +} + + + + +int slsDetector::overwriteFile(int enable){ + int fnum=F_ENABLE_RECEIVER_OVERWRITE; + int ret = FAIL; + int retval=-1; + int arg = enable; + + + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ + if(enable>=0){ + pthread_mutex_lock(&ms); + parentDet->enableOverwriteMask(enable); + pthread_mutex_unlock(&ms); + } + } + + else if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending enable file write to receiver " << arg << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + if(ret!=FAIL){ + pthread_mutex_lock(&ms); + parentDet->enableOverwriteMask(retval); + pthread_mutex_unlock(&ms); + } + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + pthread_mutex_lock(&ms); + retval = parentDet->enableOverwriteMask(); + pthread_mutex_unlock(&ms); + + return retval; +} + + + + +int slsDetector::setFrameIndex(int index){ + int fnum=F_SET_RECEIVER_FRAME_INDEX; + int ret = FAIL; + int retval=-1; + int arg = index; + + if(thisDetector->receiverOnlineFlag==OFFLINE_FLAG){ + fileIO::setFrameIndex(index); + } + + else if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending frame index to receiver " << arg << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum,retval,arg); + disconnectData(); + if(ret!=FAIL) + fileIO::setFrameIndex(retval); + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + return fileIO::getFrameIndex(); +} + + +int slsDetector::calibratePedestal(int frames){ + int ret=FAIL; + int retval=-1; + int fnum=F_CALIBRATE_PEDESTAL; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Calibrating Pedestal " <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&frames,sizeof(frames)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; +} + + + +int64_t slsDetector::clearAllErrorMask(){ + clearErrorMask(); + + pthread_mutex_lock(&ms); + for(int i=0;igetNumberOfDetectors();i++){ + if(parentDet->getDetectorId(i) == getDetectorId()) + parentDet->setErrorMask(parentDet->getErrorMask()|(0<sendInt(fnum,retval,arg); + disconnectData(); + if(ret==FAIL) + retval = -1; + if(ret==FORCE_UPDATE) + updateReceiver(); + } + + if ((i > 0) && (retval != i)){ + cout << "could not set receiver read frequency:" << retval << endl; + setErrorMask((getErrorMask())|(RECEIVER_READ_FREQUENCY)); + } + return retval; +} + + +int slsDetector::enableReceiverCompression(int i){ + int fnum=F_ENABLE_RECEIVER_COMPRESSION; + int ret = FAIL; + int retval=-1; + + + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Getting/Enabling/Disabling Receiver Compression with argument " << i << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum,retval,i); + disconnectData(); + if(ret==FAIL) + setErrorMask((getErrorMask())|(COULDNOT_ENABLE_COMPRESSION)); + } + return retval; +} + + + +void slsDetector::setDetectorHostname(){ + int fnum=F_SEND_RECEIVER_DETHOSTNAME; + int ret = FAIL; + char retval[MAX_STR_LENGTH]=""; + + + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Sending detector hostname to Receiver " << thisDetector->hostname << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendString(fnum,retval,thisDetector->hostname); + disconnectData(); + if((ret==FAIL) || (strcmp(retval,thisDetector->hostname))) + setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTNAME_NOT_SET)); + } +} + + + +int slsDetector::enableTenGigabitEthernet(int i){ + int ret=FAIL; + int retval = -1; + int fnum=F_ENABLE_TEN_GIGA,fnum2 = F_ENABLE_RECEIVER_TEN_GIGA; + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<< std::endl<< "Enabling / Disabling 10Gbe" << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&i,sizeof(i)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(DETECTOR_TEN_GIGA)); + } + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + + if(ret!=FAIL){ + //must also configuremac + if((i != -1)&&(retval == i)) + if(configureMAC() != FAIL){ + ret = FAIL; + retval=-1; + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + std::cout << "Enabling / Disabling 10Gbe in receiver: " << i << std::endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum2,retval,i); + disconnectData(); + if(ret==FAIL) + setErrorMask((getErrorMask())|(RECEIVER_TEN_GIGA)); + } + } + } + + if(ret != FAIL) + thisDetector->tenGigaEnable=retval; + return retval; +} + + + + +int slsDetector::setReceiverFifoDepth(int i){ + int fnum=F_SET_RECEIVER_FIFO_DEPTH; + int ret = FAIL; + int retval=-1; + + + if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +#ifdef VERBOSE + if(i ==-1) + std::cout<< "Getting Receiver Fifo Depth" << endl; + else + std::cout<< "Setting Receiver Fifo Depth to " << i << endl; +#endif + if (connectData() == OK) + ret=thisReceiver->sendInt(fnum,retval,i); + disconnectData(); + if(ret==FAIL) + setErrorMask((getErrorMask())|(COULD_NOT_SET_FIFO_DEPTH)); + } + return retval; +} + + + + + + /******** CTB funcs */ + + /** opens pattern file and sends pattern to CTB + @param fname pattern file to open + @returns OK/FAIL + */ +int slsDetector::setCTBPattern(string fname) { + + + int fnum=F_SET_CTB_PATTERN; + int ret = FAIL; + char retval[MAX_STR_LENGTH]=""; + + +// if(setReceiverOnline(ONLINE_FLAG)==ONLINE_FLAG){ +// #ifdef VERBOSE +// std::cout << "Sending detector hostname to Receiver " << thisDetector->hostname << std::endl; +// #endif +// if (connectData() == OK) +// ret=thisReceiver->sendString(fnum,retval,thisDetector->hostname); +// if((ret==FAIL) || (strcmp(retval,thisDetector->hostname))) +// setErrorMask((getErrorMask())|(RECEIVER_DET_HOSTNAME_NOT_SET)); +// } + + + + uint64_t word; + + int addr=0; + + FILE *fd=fopen(fname.c_str(),"r"); + if (fd>0) { + while (fread(&word, sizeof(word), 1,fd)) { + setCTBWord(addr,word); + // cout << hex << addr << " " << word << dec << endl; + addr++; + } + + fclose(fd); + } else + return -1; + + + + + + return addr; + + +} + + + /** Writes a pattern word to the CTB + @param addr address of the word, -1 is I/O control register, -2 is clk control register + @param word 64bit word to be written, -1 gets + @returns actual value + */ +uint64_t slsDetector::setCTBWord(int addr,uint64_t word) { + + //uint64_t ret; + + int ret=FAIL; + uint64_t retval=-1; + int fnum=F_SET_CTB_PATTERN; + int mode=0; //sets word + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&addr,sizeof(addr)); + controlSocket->SendDataOnly(&word,sizeof(word)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + +} + + /** Sets the pattern or loop limits in the CTB + @param level -1 complete pattern, 0,1,2, loop level + @param start start address if >=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ +int slsDetector::setCTBPatLoops(int level,int &start, int &stop, int &n) { + + + int retval[3], args[4]; + + args[0]=level; + args[1]=start; + args[2]=stop; + args[3]=n; + + + int ret=FAIL; + int fnum=F_SET_CTB_PATTERN; + int mode=1; //sets loop + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&args,sizeof(args)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + start=retval[0]; + stop=retval[1]; + n=retval[2]; + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; + + +} + + + /** Sets the wait address in the CTB + @param level 0,1,2, wait level + @param addr wait address, -1 gets + @returns actual value + */ +int slsDetector::setCTBPatWaitAddr(int level, int addr) { + + + + + int retval=-1; + + + int ret=FAIL; + int fnum=F_SET_CTB_PATTERN; + int mode=2; //sets loop + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&level,sizeof(level)); + controlSocket->SendDataOnly(&addr,sizeof(addr)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + + +} + + /** Sets the wait time in the CTB + @param level 0,1,2, wait level + @param t wait time, -1 gets + @returns actual value + */ +int slsDetector::setCTBPatWaitTime(int level, uint64_t t) { + + + + + + uint64_t retval=-1; + + + int ret=FAIL; + // uint64_t retval=-1; + int fnum=F_SET_CTB_PATTERN; + int mode=3; //sets loop + + char mess[MAX_STR_LENGTH]=""; + +#ifdef VERBOSE + std::cout<<"Setting CTB word" <onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&mode,sizeof(mode)); + controlSocket->SendDataOnly(&level,sizeof(level)); + controlSocket->SendDataOnly(&t,sizeof(t)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret!=FAIL) { + controlSocket->ReceiveDataOnly(&retval,sizeof(retval)); + } else { + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return retval; + + +} + +int slsDetector::pulsePixel(int n,int x,int y) { + int ret=FAIL; + int fnum=F_PULSE_PIXEL; + char mess[MAX_STR_LENGTH]=""; + int arg[3]; + arg[0] = n; arg[1] = x; arg[2] = y; + +#ifdef VERBOSE + std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times at (" << x << "," << "y)" << endl << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + +int slsDetector::pulsePixelNMove(int n,int x,int y) { + int ret=FAIL; + int fnum=F_PULSE_PIXEL_AND_MOVE; + char mess[MAX_STR_LENGTH]=""; + int arg[3]; + arg[0] = n; arg[1] = x; arg[2] = y; + +#ifdef VERBOSE + std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times and move by deltax:" << x << " deltay:" << y << endl << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(arg,sizeof(arg)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_PULSE_PIXEL_NMOVE)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + +int slsDetector::pulseChip(int n) { + int ret=FAIL; + int fnum=F_PULSE_CHIP; + char mess[MAX_STR_LENGTH]=""; + + +#ifdef VERBOSE + std::cout<< std::endl<< "Pulsing Pixel " << n << " number of times" << endl << endl; +#endif + + if (thisDetector->onlineFlag==ONLINE_FLAG) { + if (connectControl() == OK){ + controlSocket->SendDataOnly(&fnum,sizeof(fnum)); + controlSocket->SendDataOnly(&n,sizeof(n)); + controlSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==FAIL){ + controlSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Detector returned error: " << mess << std::endl; + setErrorMask((getErrorMask())|(COULD_NOT_PULSE_CHIP)); + } + disconnectControl(); + if (ret==FORCE_UPDATE) + updateDetector(); + } + } + + return ret; +} + + + +void slsDetector::setAcquiringFlag(bool b){ + thisDetector->acquiringFlag = b; +} + +bool slsDetector::getAcquiringFlag(){ + return thisDetector->acquiringFlag; +} diff --git a/slsDetectorSoftware/slsDetector/slsDetector.h b/slsDetectorSoftware/slsDetector/slsDetector.h new file mode 100644 index 000000000..673729b22 --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetector.h @@ -0,0 +1,1904 @@ + + + +#ifndef SLS_DETECTOR_H +#define SLS_DETECTOR_H + + +#include "multiSlsDetector.h" +#include "slsDetectorUtils.h" +#include "energyConversion.h" +#include "angleConversionConstant.h" +#include "MySocketTCP.h" + +#include "angleConversionConstant.h" + +#include "receiverInterface.h" + + +/** + * + * @short the slsDetector class takes care of the communication with the detector and all kind actions related with a single detector controller + * @author Anna Bergamaschi + * @version 0.1alpha + */ + +#define NMODMAXX 24 +#define NMODMAXY 24 +#define NCHIPSMAX 10 +#define NCHANSMAX 65536 +#define NDACSMAX 16 + + +/** + @short complete detector functionalities for a single module detector +*/ +class slsDetector : public slsDetectorUtils, public energyConversion { + + + + public: + + /* /\** online flags enum \sa setOnline*\/ */ + /* enum {GET_ONLINE_FLAG=-1, /\**< returns wether the detector is in online or offline state *\/ */ + /* OFFLINE_FLAG=0, /\**< detector in offline state (i.e. no communication to the detector - using only local structure - no data acquisition possible!) *\/ */ + /* ONLINE_FLAG =1/\**< detector in online state (i.e. communication to the detector updating the local structure) *\/ */ + /* }; */ + + + + /** + @short Structure allocated in shared memory to store detector settings. + + Structure allocated in shared memory to store detector settings and be accessed in parallel by several applications on the same machine (take care of possible conflicts, particularly if things are run on different machines!) + + */ + typedef struct sharedSlsDetector { + /** already existing flag. If the detector does not yet exist (alreadyExisting=0) the sharedMemory will be created, otherwise it will simly be linked */ + int alreadyExisting; + + + + + /** last process id accessing the shared memory */ + + pid_t lastPID; + + + + + /** online flag - is set if the detector is connected, unset if socket connection is not possible */ + int onlineFlag; + + + /** stopped flag - is set if an acquisition error occurs or the detector is stopped manually. Is reset to 0 at the start of the acquisition */ + int stoppedFlag; + + /** is the hostname (or IP address) of the detector. needs to be set before startin the communication */ + char hostname[MAX_STR_LENGTH]; + + /** is the port used for control functions normally it should not be changed*/ + int controlPort; + /** is the port used to stop the acquisition normally it should not be changed*/ + int stopPort; + + /** detector type \ see :: detectorType*/ + detectorType myDetectorType; + + + /** path of the trimbits/settings files */ + char settingsDir[MAX_STR_LENGTH]; + /** path of the calibration files */ + char calDir[MAX_STR_LENGTH]; + /** number of energies at which the detector has been trimmed (unused) */ + int nTrimEn; + /** list of the energies at which the detector has been trimmed (unused) */ + int trimEnergies[100]; + + + /** indicator for the acquisition progress - set to 0 at the beginning of the acquisition and incremented every time that the data are written to file */ + int progressIndex; + /** total number of frames to be acquired */ + int totalProgress; + + /** path of the output files */ + char filePath[MAX_STR_LENGTH]; + + /* size of the detector */ + + /** number of installed modules of the detector (x and y directions) */ + int nMod[2]; + /** number of modules ( nMod[X]*nMod[Y]) \see nMod */ + int nMods; + /** maximum number of modules of the detector (x and y directions) */ + int nModMax[2]; + /** maximum number of modules (nModMax[X]*nModMax[Y]) \see nModMax */ + int nModsMax; + /** number of channels per chip */ + int nChans; + /** number of channels per chip in one direction */ + int nChan[2]; + /** number of chips per module*/ + int nChips; + /** number of chips per module in one direction */ + int nChip[2]; + /** number of dacs per module*/ + int nDacs; + /** number of adcs per module */ + int nAdcs; + /** number of extra gain values*/ + int nGain; + /** number of extra offset values */ + int nOffset; + /** dynamic range of the detector data */ + int dynamicRange; + /** size of the data that are transfered from the detector */ + int dataBytes; + + + + /** corrections to be applied to the data \see ::correctionFlags */ + int correctionMask; + /** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */ + int threadedProcessing; + /** dead time (in ns) for rate corrections */ + double tDead; + /** directory where the flat field files are stored */ + char flatFieldDir[MAX_STR_LENGTH]; + /** file used for flat field corrections */ + char flatFieldFile[MAX_STR_LENGTH]; + /** number of bad channels from bad channel list */ + int nBadChans; + /** file with the bad channels */ + char badChanFile[MAX_STR_LENGTH]; + /** list of bad channels */ + int badChansList[MAX_BADCHANS]; + /** number of bad channels from flat field i.e. channels which read 0 in the flat field file */ + int nBadFF; + /** list of bad channels from flat field i.e. channels which read 0 in the flat field file */ + int badFFList[MAX_BADCHANS]; + + /** file with the angular conversion factors */ + char angConvFile[MAX_STR_LENGTH]; + /** array of angular conversion constants for each module \see ::angleConversionConstant */ + angleConversionConstant angOff[MAXMODS]; + /** angular direction (1 if it corresponds to the encoder direction i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */ + int angDirection; + /** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */ + double fineOffset; + /** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */ + double globalOffset; + /** number of positions at which the detector should acquire */ + int numberOfPositions; + /** list of encoder positions at which the detector should acquire */ + double detPositions[MAXPOS]; + /** bin size for data merging */ + double binSize; + /** add encoder value flag (i.e. wether the detector is moving - 1 - or stationary - 0) */ + int moveFlag; + + + /* infos necessary for the readout to determine the size of the data */ + + /** number of rois defined */ + int nROI; + /** list of rois */ + ROI roiLimits[MAX_ROIS]; + + /** readout flags */ + readOutFlags roFlags; + + + /* detector setup - not needed */ + /** name root of the output files */ + char settingsFile[MAX_STR_LENGTH]; + /** detector settings (standard, fast, etc.) */ + detectorSettings currentSettings; + /** detector threshold (eV) */ + int currentThresholdEV; + /** timer values */ + int64_t timerValue[MAX_TIMERS]; + /** clock divider */ + //int clkDiv; + + + /** Scans and scripts */ + ////////////////////////// only in the multi detector class?!?!?!? additional shared memory class?!?!?!? + int actionMask; + + mystring actionScript[MAX_ACTIONS]; + + mystring actionParameter[MAX_ACTIONS]; + + + int scanMode[MAX_SCAN_LEVELS]; + mystring scanScript[MAX_SCAN_LEVELS]; + mystring scanParameter[MAX_SCAN_LEVELS]; + int nScanSteps[MAX_SCAN_LEVELS]; + mysteps scanSteps[MAX_SCAN_LEVELS]; + int scanPrecision[MAX_SCAN_LEVELS]; + + //////////////////////////////////////////////////////////////////////////////////////////////// + + + /*offsets*/ + /** memory offsets for the flat field coefficients */ + int ffoff; + /** memory offsets for the flat filed coefficient errors */ + int fferroff; + /** memory offsets for the module structures */ + int modoff; + /** memory offsets for the dac arrays */ + int dacoff; + /** memory offsets for the adc arrays */ + int adcoff; + /** memory offsets for the chip register arrays */ + int chipoff; + /** memory offsets for the channel register arrays -trimbits*/ + int chanoff; + /** memory offsets for the gain register arrays */ + int gainoff; + /** memory offsets for the offset register arrays -trimbits*/ + int offsetoff; + + + /* receiver*/ + /** ip address/hostname of the receiver for the client to connect to**/ + char receiver_hostname[MAX_STR_LENGTH]; + /** is the port used to communicate between client and the receiver*/ + int receiverTCPPort; + /** is the port used to communicate between detector and the receiver*/ + int receiverUDPPort; + /** is the port used to communicate between second half module of Eiger detector and the receiver*/ + int receiverUDPPort2; + /** ip address of the receiver for the detector to send packets to**/ + char receiverUDPIP[MAX_STR_LENGTH]; + /** mac address of receiver for the detector to send packets to **/ + char receiverUDPMAC[MAX_STR_LENGTH]; + /** mac address of the detector **/ + char detectorMAC[MAX_STR_LENGTH]; + /** ip address of the detector **/ + char detectorIP[MAX_STR_LENGTH]; + /** online flag - is set if the receiver is connected, unset if socket connection is not possible */ + int receiverOnlineFlag; + + /** 10 Gbe enable*/ + int tenGigaEnable; + + /** flag for acquiring */ + bool acquiringFlag; + + } sharedSlsDetector; + + + + + + + + using slsDetectorUtils::getDetectorType; + + using postProcessing::flatFieldCorrect; + using postProcessing::rateCorrect; + using postProcessing::setBadChannelCorrection; + + using angularConversion::readAngularConversion; + using angularConversion::writeAngularConversion; + + using slsDetectorUtils::getAngularConversion; + + + string getDetectorType(){return sgetDetectorsType();}; + + + + /** (default) constructor + \param type is needed to define the size of the detector shared memory 9defaults to GENERIC i.e. the largest shared memory needed by any slsDetector is allocated + \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently + \param p is the parent multislsdet to access filename ,path etc + + */ + + slsDetector(detectorType type=GENERIC, int id=0, multiSlsDetector *p=NULL); + + /** constructor + \param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently + \param p is the parent multislsdet to access filename ,path etc + */ + slsDetector(int id, multiSlsDetector *p=NULL); + + + slsDetector(char *name, int id=0, int cport=DEFAULT_PORTNO, multiSlsDetector *p=NULL); + //slsDetector(string const fname); + // ~slsDetector(){while(dataQueue.size()>0){}}; + /** destructor */ + virtual ~slsDetector(); + + int setOnline(int const online=GET_ONLINE_FLAG); + + string checkOnline(); + + /** @short activates the detector (detector specific) + \param enable can be: -1 returns wether the detector is in active (1) or inactive (0) state + \returns 0 (inactive) or 1 (active) + */ + int activate(int const enable=GET_ONLINE_FLAG); + + + /** returns if the detector already existed + \returns 1 if the detector structure has already be initlialized, 0 otherwise */ + int exists() {return thisDetector->alreadyExisting;}; + + /** returns 1 if the detetcor with id has already been allocated and initialized in shared memory + \param detector id + \returns 1 if the detector structure has already be initlialized, 0 otherwise */ + static int exists(int id); + + /** + configures mac for gotthard, moench readout + \returns OK or FAIL + */ + int configureMAC(); + + /** + Prints receiver configuration + \returns OK or FAIL + */ + int printReceiverConfiguration(); + + /** + Reads the configuration file fname + \param fname file name + \returns OK or FAIL + */ + int readConfigurationFile(string const fname); + + + int readConfigurationFile(ifstream &infile); + + + + /** + + Writes the configuration file fname + \param fname file name + \returns OK or FAIL + + */ + int writeConfigurationFile(string const fname); + int writeConfigurationFile(ofstream &outfile, int id=-1); + + + + + + + + + /** + configure the socket communication and initializes the socket instances + + \param name hostname - if "" the current hostname is used + \param control_port port for control commands - if -1 the current is used + \param stop_port port for stop command - if -1 the current is used + + \returns OK is connection succeded, FAIL otherwise + \sa sharedSlsDetector + */ + int setTCPSocket(string const name="", int const control_port=-1, int const stop_port=-1); + + /** + changes/gets the port number + \param type port type + \param num new port number (-1 gets) + \returns actual port number + */ + int setPort(portType type, int num=-1); + + /** returns the detector control port \sa sharedSlsDetector */ + int getControlPort() {return thisDetector->controlPort;}; + /** returns the detector stop port \sa sharedSlsDetector */ + int getStopPort() {return thisDetector->stopPort;}; + /** returns the receiver port \sa sharedSlsDetector */ + int getReceiverPort() {return thisDetector->receiverTCPPort;}; + + /** Locks/Unlocks the connection to the server + /param lock sets (1), usets (0), gets (-1) the lock + /returns lock status of the server + */ + int lockServer(int lock=-1); + + /** + Returns the IP of the last client connecting to the detector + */ + string getLastClientIP(); + + /** returns the detector hostname \sa sharedSlsDetector */ + string getHostname(int ipos=-1) {return string(thisDetector->hostname);}; + /** returns the detector hostname \sa sharedSlsDetector */ + string setHostname(const char *name, int ipos=-1) {setTCPSocket(string(name)); return string(thisDetector->hostname);}; + /** connect to the control port */ + int connectControl(); + /** disconnect from the control port */ + int disconnectControl(); + + /** connect to the receiver port */ + int connectData(); + /** disconnect from the receiver port */ + int disconnectData(); + + /** connect to the stop port */ + int connectStop(); + /** disconnect from the stop port */ + int disconnectStop(); + + /** + sets the network parameters + \param i network parameter type can be RECEIVER_IP, RECEIVER_MAC, SERVER_MAC + \param s value to be set + \returns parameter + + */ + char* setNetworkParameter(networkParameter index, string value); + + /** + gets the network parameters + \param i network parameter type can be RECEIVER_IP, RECEIVER_MAC, SERVER_MAC + \returns parameter + + */ + char* getNetworkParameter(networkParameter index); + + /* I/O */ + + /** returns the detector trimbit/settings directory \sa sharedSlsDetector */ + char* getSettingsDir() {return thisDetector->settingsDir;}; + /** sets the detector trimbit/settings directory \sa sharedSlsDetector */ + char* setSettingsDir(string s) {sprintf(thisDetector->settingsDir, s.c_str()); return thisDetector->settingsDir;}; + + + + /** + returns the location of the calibration files + \sa sharedSlsDetector + */ + char* getCalDir() {return thisDetector->calDir;}; + /** + sets the location of the calibration files + \sa sharedSlsDetector + */ + char* setCalDir(string s) {sprintf(thisDetector->calDir, s.c_str()); return thisDetector->calDir;}; + + + + /** returns the number of trim energies and their value \sa sharedSlsDetector + \param point to the array that will contain the trim energies (in ev) + \returns number of trim energies + + + unused! + + \sa sharedSlsDetector + */ + int getTrimEn(int *en=NULL) {if (en) {for (int ien=0; iennTrimEn; ien++) en[ien]=thisDetector->trimEnergies[ien];} return (thisDetector->nTrimEn);}; + + + /** sets the number of trim energies and their value \sa sharedSlsDetector + \param nen number of energies + \param en array of energies + \returns number of trim energies + + unused! + + \sa sharedSlsDetector + */ + int setTrimEn(int nen, int *en=NULL) {if (en) {for (int ien=0; ientrimEnergies[ien]=en[ien]; thisDetector->nTrimEn=nen;} return (thisDetector->nTrimEn);}; + + + //virtual int writeSettingsFile(string fname, sls_detector_module mod); + + /** + writes a trim/settings file for module number imod - the values will be read from the current detector structure + \param fname name of the file to be written + \param imod module number + \param iodelay io delay (detector specific) + \returns OK or FAIL if the file could not be written + \sa ::sls_detector_module sharedSlsDetector mythenDetector::writeSettingsFile(string, int) + */ + using energyConversion::writeSettingsFile; + int writeSettingsFile(string fname, int imod, int* iodelay=0); + + + /** + returns currently the loaded trimfile/settingsfile name + */ + const char *getSettingsFile(){\ + string s(thisDetector->settingsFile); \ + if (s.length()>6) {\ + if (s.substr(s.length()-6,3)==string(".sn") && s.substr(s.length()-3)!=string("xxx") ) \ + return s.substr(0,s.length()-6).c_str(); \ + } \ + return thisDetector->settingsFile;\ + }; + + + + /** loads the modules settings/trimbits reading from a file + \param fname file name . If not specified, extension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int loadSettingsFile(string fname, int imod=-1); + + + /** saves the modules settings/trimbits writing to a file + \param fname file name . Axtension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int saveSettingsFile(string fname, int imod=-1); + + /** sets all the trimbits to a particular value + \param val trimbit value + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int setAllTrimbits(int val, int imod=-1); + + + /** loads the modules calibration data reading from a file + \param fname file name . If not specified, extension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int loadCalibrationFile(string fname, int imod=-1); + + + /** saves the modules calibration data writing to a file + \param fname file name . Axtension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + int saveCalibrationFile(string fname, int imod=-1); + + + /** + + reads an angular conversion file + \param fname file to be read + \sa angleConversionConstant mythenDetector::readAngularConversion + */ + int readAngularConversionFile(string fname=""); + + + /** + + reads an angular conversion file + \param fname file to be read + \sa angleConversionConstant mythenDetector::readAngularConversion + */ + int readAngularConversion(ifstream& ifs); + + + + /** + Pure virtual function + writes an angular conversion file + \param fname file to be written + \sa angleConversionConstant mythenDetector::writeAngularConversion + */ + int writeAngularConversion(string fname=""); + + + + /** + Pure virtual function + writes an angular conversion file + \param fname file to be written + \sa angleConversionConstant mythenDetector::writeAngularConversion + */ + int writeAngularConversion(ofstream &ofs); + + + + + + /** Returns the number of channels per chip (without connecting to the detector) */ + int getNChans(){return thisDetector->nChans;}; // + + /** Returns the number of channels per chip (without connecting to the detector) in one direction */ + int getNChans(dimension d){return thisDetector->nChan[d];}; // + + /** Returns the number of chips per module (without connecting to the detector) */ + int getNChips(){return thisDetector->nChips;}; // + + /** Returns the number of chips per module (without connecting to the detector) */ + int getNChips(dimension d){return thisDetector->nChip[d];}; // + + /** Returns the number of modules (without connecting to the detector) */ + int getNMods(){return thisDetector->nMods;}; // + + /** Returns the number of modules in direction d (without connecting to the detector) */ + int getNMod(dimension d){return thisDetector->nMod[d];}; // + + int getChansPerMod(int imod=0){return thisDetector->nChans*thisDetector->nChips;}; + + int getChansPerMod( dimension d,int imod=0){return thisDetector->nChan[d]*thisDetector->nChip[d];}; + + /** Returns the max number of modules in direction d (without connecting to the detector) */ + int getNMaxMod(dimension d){return thisDetector->nModMax[d];}; // + + /** Returns the number of modules (without connecting to the detector) */ + int getMaxMods(){return thisDetector->nModsMax;}; // + + + int getTotalNumberOfChannels(){return thisDetector->nChans*thisDetector->nChips*thisDetector->nMods;}; + + int getTotalNumberOfChannels(dimension d){return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nMod[d];}; + + int getMaxNumberOfChannels(){return thisDetector->nChans*thisDetector->nChips*thisDetector->nModsMax;}; + + int getMaxNumberOfChannels(dimension d){return thisDetector->nChan[d]*thisDetector->nChip[d]*thisDetector->nModMax[d];}; + + /** Returns number of rois */ + int getNRoi(){return thisDetector->nROI;}; + + + + /* Communication to server */ + + + /** + executes a system command on the server + e.g. mount an nfs disk, reboot and returns answer etc. + \param cmd is the command to be executed + \param answer is the answer from the detector + \returns OK or FAIL depending on the command outcome + */ + int execCommand(string cmd, string answer); + + /** + sets/gets detector type + normally the detector knows what type of detector it is + \param type is the detector type (defaults to GET_DETECTOR_TYPE) + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) + */ + int setDetectorType(detectorType type=GET_DETECTOR_TYPE); + + /** + sets/gets detector type + normally the detector knows what type of detector it is + \param type is the detector type ("Mythen", "Pilatus", "XFS", "Gotthard", Agipd", "Mönch") + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH, -1 command failed) + */ + int setDetectorType(string type); + + /** + gets detector type + normally the detector knows what type of detector it is + \returns returns detector type index (1 GENERIC, 2 MYTHEN, 3 PILATUS, 4 XFS, 5 GOTTHARD, 6 AGIPD, 7 MOENCH,-1 command failed) + */ + detectorType getDetectorsType(int pos=-1); + + detectorType setDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorsType(pos);}; + + string sgetDetectorsType(int pos=-1){return getDetectorType(getDetectorsType(pos));}; + + string ssetDetectorsType(detectorType type=GET_DETECTOR_TYPE, int pos=-1){return getDetectorType(getDetectorsType(pos));}; + string ssetDetectorsType(string t, int pos=-1){return getDetectorType(getDetectorsType(pos));} + + // Detector configuration functions + /** + set/get the size of the detector + \param n number of modules + \param d dimension + \returns current number of modules in direction d + */ + + // Detector configuration functions + /** + set/get the size of the detector + \param n number of modules + \param d dimension + \returns current number of modules in direction d + */ + int setNumberOfModules(int n=GET_FLAG, dimension d=X); // if n=GET_FLAG returns the number of installed modules + + + + + /* + returns the instrinsic size of the detector (maxmodx, maxmody, nchans, nchips, ndacs + enum numberOf { + MAXMODX, + MAXMODY, + CHANNELS, + CHIPS, + DACS + } + */ + + + /** + get the maximum size of the detector + \param d dimension + \returns maximum number of modules that can be installed in direction d + */ + int getMaxNumberOfModules(dimension d=X); // + + + /** + set/get the use of an external signal + \param pol meaning of the signal \sa externalSignalFlag + \param signalIndex index of the signal + \returns current meaning of signal signalIndex + */ + externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0); + + + /** + set/get the external communication mode + + obsolete \sa setExternalSignalFlags + \param pol value to be set \sa externalCommunicationMode + \returns current external communication mode + */ + externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE); + + + // Tests and identification + + /** + get detector ids/versions for module + \param mode which id/version has to be read + \param imod module number for module serial number + \returns id + */ + int64_t getId(idMode mode, int imod=0); + /** + Digital test of the modules + \param mode test mode + \param imod module number for chip test or module firmware test + \returns OK or error mask + */ + int digitalTest(digitalTestMode mode, int imod=0); + /** + analog test + \param modte test mode + \return pointer to acquired data + + not yet implemented + */ + + int* analogTest(analogTestMode mode); + + /** + enable analog output of channel ichan + + not yet implemented + */ + int enableAnalogOutput(int ichan); + + /** + enable analog output of channel ichan, chip ichip, module imod + + not yet implemented + */ + int enableAnalogOutput(int imod, int ichip, int ichan); + + /** + give a train of calibration pulses + \param vcal pulse amplitude + \param npulses number of pulses + + not yet implemented + + */ + int giveCalibrationPulse(double vcal, int npulses); + + // Expert Initialization functions + + + /** + write register + \param addr address + \val value + \returns current register value + + */ + int writeRegister(int addr, int val); + + + /** + write register + \param addr address + \val value + \returns current register value + + */ + int writeAdcRegister(int addr, int val); + + /** + read register + \param addr address + \returns current register value + + */ + int readRegister(int addr); + + /** + set dacs value + \param val value (in V) + \param index DAC index + \param mV 0 in dac units or 1 in mV + \param imod module number (if -1 alla modules) + \returns current DAC value + */ + dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1); + + /** + set dacs value + \param index ADC index + \param imod module number + \returns current ADC value + */ + dacs_t getADC(dacIndex index, int imod=0); + + /** + configure channel + \param reg channel register + \param ichan channel number (-1 all) + \param ichip chip number (-1 all) + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_channel + */ + int setChannel(int64_t reg, int ichan=-1, int ichip=-1, int imod=-1); + + /** + configure channel + \param chan channel to be set - must contain correct channel, module and chip number + \returns current register value + */ + int setChannel(sls_detector_channel chan); + + /** + get channel + \param ichan channel number + \param ichip chip number + \param imod module number + \returns current channel structure for channel + */ + sls_detector_channel getChannel(int ichan, int ichip, int imod); + + + + /** + configure chip + \param reg chip register + \param ichip chip number (-1 all) + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_chip + */ + int setChip(int reg, int ichip=-1, int imod=-1); + + /** + configure chip + \param chip chip to be set - must contain correct module and chip number and also channel registers + \returns current register value + \sa ::sls_detector_chip + */ + int setChip(sls_detector_chip chip); + + /** + get chip + \param ichip chip number + \param imod module number + \returns current chip structure for channel + + \bug probably does not return corretly! + */ + sls_detector_chip getChip(int ichip, int imod); + + + /** + configure module + \param imod module number (-1 all) + \returns current register value + \sa ::sls_detector_module + */ + int setModule(int reg, int imod=-1); + //virtual int setModule(int reg, int imod=-1); + + /** + configure chip + \param module module to be set - must contain correct module number and also channel and chip registers + \param gainval pointer to extra gain values + \param offsetval pointer to extra offset values + \param iodelay iodelay (detector specific) + \param tau tau (detector specific) + \returns current register value + \sa ::sls_detector_module + */ + int setModule(sls_detector_module module, int* gainval, int* offsetval,int* iodelay, int64_t tau); + //virtual int setModule(sls_detector_module module); + + /** + get module + \param imod module number + \returns pointer to module structure (which has bee created and must then be deleted) + */ + sls_detector_module *getModule(int imod); + //virtual sls_detector_module *getModule(int imod); + + // calibration functions + // int setCalibration(int imod, detectorSettings isettings, double gain, double offset); + //int getCalibration(int imod, detectorSettings isettings, double &gain, double &offset); + + + /* + calibrated setup of the threshold + */ + /** + get threshold energy + \param imod module number (-1 all) + \returns current threshold value for imod in ev (-1 failed) + */ + int getThresholdEnergy(int imod=-1); + + /** + set threshold energy + \param e_eV threshold in eV + \param imod module number (-1 all) + \param isettings ev. change settings + \returns current threshold value for imod in ev (-1 failed) + */ + int setThresholdEnergy(int e_eV, int imod=-1, detectorSettings isettings=GET_SETTINGS); + + /** + get detector settings + \param imod module number (-1 all) + \returns current settings + */ + detectorSettings getSettings(int imod=-1); + + /** + set detector settings + \param isettings settings + \param imod module number (-1 all) + \returns current settings + + in this function trimbits/settings and calibration files are searched in the settingsDir and calDir directories and the detector is initialized + */ + detectorSettings setSettings(detectorSettings isettings, int imod=-1); + //virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1); + + /** + gets the trimbits from shared memory *chanRegs + \param retval is the array with the trimbits + \param fromDetector is true if the trimbits shared memory have to be uploaded from detector + \returns the total number of channels for the detector + \sa ::sls_detector_module + */ + int getChanRegs(double* retval,bool fromDetector); + + /** + + updates the shared memory receiving the data from the detector (without asking and closing the connection + /returns OK + + */ + + int updateDetectorNoWait(); + + /** + + updates the shared memory receiving the data from the detector + /returns OK + + */ + + + int updateDetector(); + + // Acquisition functions + + + /** + start detector acquisition + \returns OK/FAIL + */ + int startAcquisition(); + + /** + stop detector acquisition + \returns OK/FAIL + */ + int stopAcquisition(); + + /** + start readout (without exposure or interrupting exposure) + \returns OK/FAIL + */ + int startReadOut(); + + /** + get run status + \returns status mask + */ + //virtual runStatus getRunStatus()=0; + runStatus getRunStatus(); + + /** + start detector acquisition and read all data putting them a data queue + \returns pointer to the front of the data queue + \sa startAndReadAllNoWait getDataFromDetector dataQueue + */ + int* startAndReadAll(); + + /** + start detector acquisition and read out, but does not read data from socket leaving socket opened + \returns OK or FAIL + + */ + int startAndReadAllNoWait(); + + /* /\** */ + /* receives a data frame from the detector socket */ + /* \returns pointer to the data or NULL. If NULL disconnects the socket */ + /* \sa getDataFromDetector */ + /* *\/ */ + /* int* getDataFromDetectorNoWait(); */ + + /** + asks and receives a data frame from the detector and puts it in the data queue + \returns pointer to the data or NULL. + \sa getDataFromDetector + */ + int* readFrame(); + + /** + asks and receives all data from the detector and puts them in a data queue + \returns pointer to the front of the queue or NULL. + \sa getDataFromDetector dataQueue + */ + int* readAll(); + + /** + asks and receives all data from the detector and leaves the socket opened + \returns OK or FAIL + */ + int readAllNoWait(); + + + + + + /** + set/get timer value + \param index timer index + \param t time in ns or number of...(e.g. frames, gates, probes) + \returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t setTimer(timerIndex index, int64_t t=-1); + + /** + get current timer value + \param index timer index + \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) + */ + int64_t getTimeLeft(timerIndex index); + + + + + /** sets/gets the value of important readout speed parameters + \param sp is the parameter to be set/get + \param value is the value to be set, if -1 get value + \returns current value for the specified parameter + \sa speedVariable + */ + int setSpeed(speedVariable sp, int value=-1); + + // Flags + /** + set/get dynamic range + \param n dynamic range (-1 get) + \returns current dynamic range + updates the size of the data expected from the detector + \sa sharedSlsDetector + */ + int setDynamicRange(int n=-1); + + /** + set/get dynamic range + \returns number of bytes sent by the detector + \sa sharedSlsDetector + */ + int getDataBytes(){return thisDetector->dataBytes;}; + + + /** + set roi + \param n number of rois + \param roiLimits array of roi + \returns success or failure + */ + int setROI(int n=-1,ROI roiLimits[]=NULL); + + /** + get roi from each detector and convert it to the multi detector scale + \param n number of roi + \returns an array of multidetector's rois + */ + slsDetectorDefs::ROI* getROI(int &n); + + + int sendROI(int n=-1,ROI roiLimits[]=NULL); + + /** + set/get readout flags + \param flag readout flag to be set + \returns current flag + */ + int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS); + + /** + execute trimming + \param mode trim mode + \param par1 if noise, beam or fixed setting trimming it is count limit, if improve maximum number of iterations + \param par2 if noise or beam nsigma, if improve par2!=means vthreshold will be optimized, if fixed settings par2<0 trimwith median, par2>=0 trim with level + \param imod module number (-1 all) + \returns OK or FAIl (FAIL also if some channel are 0 or 63 + */ + int executeTrimming(trimMode mode, int par1, int par2, int imod=-1); + + + //Corrections + + + /** + set flat field corrections + \param fname name of the flat field file (or "" if disable) + \returns 0 if disable (or file could not be read), >0 otherwise + */ + int setFlatFieldCorrection(string fname=""); + + /** + set flat field corrections + \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) + \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) + \returns 0 if ff correction disabled, >0 otherwise + */ + int setFlatFieldCorrection(double *corr, double *ecorr=NULL); + + + /** + get flat field corrections + \param corr if !=NULL will be filled with the correction coefficients + \param ecorr if !=NULL will be filled with the correction coefficients errors + \returns 0 if ff correction disabled, >0 otherwise + */ + int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL); + + + /** + set rate correction + \param t dead time in ns - if 0 disable correction, if >0 set dead time to t, if <0 set deadtime to default dead time for current settings + \returns 0 if rate correction disabled, >0 otherwise + */ + int setRateCorrection(double t=0); + + + /** + get rate correction + \param t reference for dead time + \returns 0 if rate correction disabled, >0 otherwise + */ + int getRateCorrection(double &t); + + + /** + get rate correction tau + \returns 0 if rate correction disabled, otherwise the tau used for the correction + */ + double getRateCorrectionTau(); + /** + get rate correction + \returns 0 if rate correction disabled, >0 otherwise + */ + int getRateCorrection(); + + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(string fname=""); + + /** + set bad channels correction + \param nch number of bad channels + \param chs array of channels + \param ff 0 if normal bad channels, 1 if ff bad channels + \returns 0 if bad channel disabled, >0 otherwise + */ + int setBadChannelCorrection(int nch, int *chs, int ff=0); + + /** + get bad channels correction + \param bad pointer to array that if bad!=NULL will be filled with the bad channel list + \returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + int getBadChannelCorrection(int *bad=NULL); + + + /** + pure virtual function + get angular conversion + \param reference to diffractometer direction + \param angconv array that will be filled with the angular conversion constants + \returns 0 if angular conversion disabled, >0 otherwise + \sa mythenDetector::getAngularConversion + */ + int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL) ; + + angleConversionConstant *getAngularConversionPointer(int imod=0) {return &thisDetector->angOff[imod];}; + + + + /** + decode data from the detector converting them to an array of doubles, one for each channle + \param datain data from the detector + \returns pointer to a double array with a data per channel + */ + double* decodeData(int *datain, double *fdata=NULL); + + + + + + /** + flat field correct data + \param datain data array + \param errin error array on data (if NULL will default to sqrt(datain) + \param dataout array of corrected data + \param errout error on corrected data (if not NULL) + \returns 0 + */ + int flatFieldCorrect(double* datain, double *errin, double* dataout, double *errout); + + + + + /** + rate correct data + \param datain data array + \param errin error array on data (if NULL will default to sqrt(datain) + \param dataout array of corrected data + \param errout error on corrected data (if not NULL) + \returns 0 + */ + int rateCorrect(double* datain, double *errin, double* dataout, double *errout); + + + /* /\** */ + /* pure virtual function */ + /* sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); */ + /* \param mp already merged postions */ + /* \param mv already merged data */ + /* \param me already merged errors (squared sum) */ + /* \param mm multiplicity of merged arrays */ + /* \returns OK or FAIL */ + /* \sa mythenDetector::resetMerging */ + /* *\/ */ + + /* int resetMerging(double *mp, double *mv,double *me, int *mm); */ + + /* /\** */ + /* pure virtual function */ + /* merge dataset */ + /* \param p1 angular positions of dataset */ + /* \param v1 data */ + /* \param e1 errors */ + /* \param mp already merged postions */ + /* \param mv already merged data */ + /* \param me already merged errors (squared sum) */ + /* \param mm multiplicity of merged arrays */ + /* \sa mythenDetector::addToMerging */ + /* *\/ */ + /* int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm); */ + + /* /\** pure virtual function */ + /* calculates the "final" positions, data value and errors for the emrged data */ + /* \param mp already merged postions */ + /* \param mv already merged data */ + /* \param me already merged errors (squared sum) */ + /* \param mm multiplicity of merged arrays */ + /* \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) */ + /* \sa mythenDetector::finalizeMerging */ + /* *\/ */ + /* int finalizeMerging(double *mp, double *mv,double *me, int *mm); */ + + /** + turns off server + */ + int exitServer(); + + + /** Allocates the memory for a sls_detector_module structure and initializes it + \returns myMod the pointer to the allocate dmemory location + + */ + sls_detector_module* createModule(){return createModule(thisDetector->myDetectorType);}; + + + /** Allocates the memory for a sls_detector_module structure and initializes it + \returns myMod the pointer to the allocate dmemory location + + */ + sls_detector_module* createModule(detectorType myDetectorType); + + /** frees the memory for a sls_detector_module structure + \param myMod the pointer to the memory to be freed + + */ + + void deleteModule(sls_detector_module *myMod); + + + /** calcualtes the total number of steps of the acquisition. + called when number of frames, number of cycles, number of positions and scan steps change + */ + int setTotalProgress(); + + /** returns the current progress in % */ + double getCurrentProgress(); + + + // double* convertAngles(double pos); + + + + + + /** + returns the detector type from hostname and controlport + \param + \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) + */ + static detectorType getDetectorType(const char *name, int cport=DEFAULT_PORTNO); + + /** + returns the detector type from hostname and controlport + \param + \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) + */ + static detectorType getDetectorType(int id); + + + /** + Returns detector id + \returns detector id + */ + + int getDetectorId(int i=-1) {return detId;}; + /** + Receives a data frame from the detector socket + \returns pointer to the data (or NULL if failed) + + */ + int* getDataFromDetector(int *retval=NULL); + + //int* + + + /** returns if the detector is Master, slave or nothing + \param flag can be GET_MASTER, NO_MASTER, IS_MASTER, IS_SLAVE + \returns master flag of the detector + */ + masterFlags setMaster(masterFlags flag); + + /** + Loads dark image or gain image from a file and sends it to the detector + \param index is 0 for dark image and 1 for gain image + \param fname file name to load data from + + */ + int loadImageToDetector(imageType index,string const fname); + + /** + Called from loadImageToDetector to send the image to detector + \param index is 0 for dark image and 1 for gain image + \param arg image + + */ + int sendImageToDetector(imageType index,short int imageVals[]); + + /** + Sets/gets the synchronization mode of the various detectors + \param sync syncronization mode can be GET_SYNCHRONIZATION_MODE, NONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS + \returns current syncronization mode + */ + synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE); + + /** + writes the counter memory block from the detector + \param startACQ is 1 to start acquisition after reading counter + \param fname file name to load data from + \returns OK or FAIL + */ + int writeCounterBlockFile(string const fname,int startACQ=0); + + + /** + gets counter memory block in detector + \param startACQ is 1 to start acquisition after reading counter + \param arg counter memory block from detector + \returns OK or FAIL + */ + int getCounterBlock(short int arg[],int startACQ=0); + + + /** + Resets counter in detector + \param startACQ is 1 to start acquisition after resetting counter + \returns OK or FAIL + */ + int resetCounterBlock(int startACQ=0); + + /** set/get counter bit in detector + * @param i is -1 to get, 0 to reset and any other value to set the counter bit + /returns the counter bit in detector + */ + int setCounterBit(int i = -1); + + + int getMoveFlag(int imod){if (moveFlag) return *moveFlag; else return 1;}; + + /** Frees the shared memory - should not be used*/ + int freeSharedMemory(); + + + + + + //receiver + + + /** + calls setReceiverTCPSocket if online and sets the flag + */ + int setReceiverOnline(int const online=GET_ONLINE_FLAG); + + /** + Checks if the receiver is really online + */ + string checkReceiverOnline(); + + /** + configure the socket communication and initializes the socket instances + + \param name receiver ip - if "" the current receiver hostname is used + \param receiver_port port for receiving data - if -1 the current is used + + \returns OK is connection succeded, FAIL otherwise + \sa sharedSlsDetector + */ + int setReceiverTCPSocket(string const name="", int const receiver_port=-1); + + + /** + Sets up the file directory + @param s fileDir file directory + \returns file dir + */ + string setFilePath(string s=""); + + /** + Sets up the file name + @param s file name + \returns file name + */ + string setFileName(string s=""); + + /** + Sets up the file index + @param i file index + \returns file index + */ + int setFileIndex(int i=-1); + + /** + \returns file dir + */ + string getFilePath(){return setFilePath();}; + + /** + \returns file name + */ + string getFileName(){return setFileName();}; + + /** + \returns file index + */ + int getFileIndex(){return setFileIndex();}; + + + /** Starts the listening mode of receiver + \returns OK or FAIL + */ + int startReceiver(); + + /** Stops the listening mode of receiver + \returns OK or FAIL + */ + int stopReceiver(); + + /** Sets the receiver to start any readout remaining in the fifo and + * change status to transmitting. + * The status changes to run_finished when fifo is empty + */ + runStatus startReceiverReadout(); + + /** Sets(false) or Resets(true) the CPU bit in detector + \returns OK or FAIL + */ + int detectorSendToReceiver(bool set); + + /** gets the status of the listening mode of receiver + \returns status + */ + runStatus getReceiverStatus(); + + /** gets the number of frames caught by receiver + \returns number of frames caught by receiver + */ + int getFramesCaughtByReceiver(); + + /** gets the current frame index of receiver + \returns current frame index of receiver + */ + int getReceiverCurrentFrameIndex(); + + /** + * resets framescaught + * @param index frames caught by receiver + */ + int resetFramesCaught(); + + /** + * Reads a frame from receiver + * @param fName file name of current frame() + * @param acquisitionIndex current acquisition index + * @param frameIndex current frame index (for each scan) + * @param subFrameIndex current sub frame index (for 32 bit mode for eiger) + /returns a frame read from recever + */ + int* readFrameFromReceiver(char* fName, int &acquisitionIndex, int &frameIndex, int &subFrameIndex); + + /** Locks/Unlocks the connection to the receiver + /param lock sets (1), usets (0), gets (-1) the lock + /returns lock status of the receiver + */ + int lockReceiver(int lock=-1); + + /** + Returns the IP of the last client connecting to the receiver + */ + string getReceiverLastClientIP(); + + /** + updates the shared memory receiving the data from the detector (without asking and closing the connection + /returns OK + */ + int updateReceiverNoWait(); + + /** + updates the shared memory receiving the data from the detector + /returns OK + */ + int updateReceiver(); + + /** + Turns off the receiver server! + */ + int exitReceiver(); + + /** + Sets/Gets receiver file write enable + @param enable 1 or 0 to set/reset file write enable + /returns file write enable + */ + int enableWriteToFile(int enable=-1); + + /** + Sets/Gets file overwrite enable + @param enable 1 or 0 to set/reset file overwrite enable + /returns file overwrite enable + */ + int overwriteFile(int enable=-1); + + + /** + * set frame index to 0 or -1 + * @param index is the frame index + */ + int setFrameIndex(int index=-1); + + + + int fillModuleMask(int *mM); + + + /** Starts acquisition, calibrates pedestal and writes to fpga + /returns number of frames + */ + int calibratePedestal(int frames = 0); + + + /** Clears error mask and also the bit in parent det multi error mask + /returns error mask + */ + int64_t clearAllErrorMask(); + + + /** returns the detector MAC address\sa sharedSlsDetector */ + char* getDetectorMAC() {return thisDetector->detectorMAC;}; + /** returns the detector IP address\sa sharedSlsDetector */ + char* getDetectorIP() {return thisDetector->detectorIP;}; + /** returns the receiver IP address \sa sharedSlsDetector */ + char* getReceiver() {return thisDetector->receiver_hostname;}; + /** returns the receiver UDP IP address \sa sharedSlsDetector */ + char* getReceiverUDPIP() {return thisDetector->receiverUDPIP;}; + /** returns the receiver UDP MAC address \sa sharedSlsDetector */ + char* getReceiverUDPMAC() {return thisDetector->receiverUDPMAC;}; + /** returns the receiver UDP IP address \sa sharedSlsDetector */ + char* getReceiverUDPPort() {char *c= new char[MAX_STR_LENGTH];sprintf(c,"%d",thisDetector->receiverUDPPort); return c;}; + /** returns the receiver UDP2 for Eiger IP address \sa sharedSlsDetector */ + char* getReceiverUDPPort2() {char *c= new char[MAX_STR_LENGTH];sprintf(c,"%d",thisDetector->receiverUDPPort2); return c;}; + + /** validates the format of detector MAC address and sets it \sa sharedSlsDetector */ + char* setDetectorMAC(string detectorMAC); + /** validates the format of detector IP address and sets it \sa sharedSlsDetector */ + char* setDetectorIP(string detectorIP); + /** validates and sets the receiver IP address/hostname \sa sharedSlsDetector */ + char* setReceiver(string receiver); + /** validates the format of receiver udp ip and sets it \sa sharedSlsDetector */ + char* setReceiverUDPIP(string udpip); + /** validates the format of receiver udp mac and sets it \sa sharedSlsDetector */ + char* setReceiverUDPMAC(string udpmac); + /** sets the receiver udp port \sa sharedSlsDetector */ + int setReceiverUDPPort(int udpport); + /** sets the receiver udp port2 for Eiger \sa sharedSlsDetector */ + int setReceiverUDPPort2(int udpport); + /** sets the transmission delay for left or right port or for an entire frame*/ + char* setDetectorNetworkParameter(networkParameter index, int delay); + + /** Sets the read receiver frequency + if Receiver read upon gui request, readRxrFrequency=0, + else every nth frame to be sent to gui + @param getFromReceiver is 1 if it should ask the receiver, + 0 if it can get it from multislsdetecter + @param i is the receiver read frequency + /returns read receiver frequency + */ + int setReadReceiverFrequency(int getFromReceiver, int i=-1); + + /** enable/disable or get data compression in receiver + * @param i is -1 to get, 0 to disable and 1 to enable + /returns data compression in receiver + */ + int enableReceiverCompression(int i = -1); + + /** send the detector host name to the eiger receiver + * for various handshaking required with the detector + */ + void setDetectorHostname(); + + /** enable/disable or 10Gbe + * @param i is -1 to get, 0 to disable and 1 to enable + /returns if 10Gbe is enabled + */ + int enableTenGigabitEthernet(int i = -1); + + /** set/get receiver fifo depth + * @param i is -1 to get, any other value to set the fifo deph + /returns the receiver fifo depth + */ + int setReceiverFifoDepth(int i = -1); + + /******** CTB funcs */ + + /** opens pattern file and sends pattern to CTB + @param fname pattern file to open + @returns OK/FAIL + */ + int setCTBPattern(string fname); + + + /** Writes a pattern word to the CTB + @param addr address of the word, -1 is I/O control register, -2 is clk control register + @param word 64bit word to be written, -1 gets + @returns actual value + */ + uint64_t setCTBWord(int addr,uint64_t word=-1); + + /** Sets the pattern or loop limits in the CTB + @param level -1 complete pattern, 0,1,2, loop level + @param start start address if >=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ + int setCTBPatLoops(int level,int &start, int &stop, int &n); + + + /** Sets the wait address in the CTB + @param level 0,1,2, wait level + @param addr wait address, -1 gets + @returns actual value + */ + int setCTBPatWaitAddr(int level, int addr=-1); + + /** Sets the wait time in the CTB + @param level 0,1,2, wait level + @param t wait time, -1 gets + @returns actual value + */ + int setCTBPatWaitTime(int level, uint64_t t=-1); + + /** + Pulse Pixel + \param n is number of times to pulse + \param x is x coordinate + \param y is y coordinate + \returns OK or FAIL + */ + int pulsePixel(int n=0,int x=0,int y=0); + + /** + Pulse Pixel and move by a relative value + \param n is number of times to pulse + \param x is relative x value + \param y is relative y value + \returns OK or FAIL + */ + int pulsePixelNMove(int n=0,int x=0,int y=0); + + /** + Pulse Chip + \param n is number of times to pulse + \returns OK or FAIL + */ + int pulseChip(int n=0); + + /** + Set acquiring flag in shared memory + \param b acquiring flag + */ + void setAcquiringFlag(bool b=false); + + /** + Get acquiring flag from shared memory + \returns acquiring flag + */ + bool getAcquiringFlag(); + + + protected: + + + /** + address of the detector structure in shared memory + */ + sharedSlsDetector *thisDetector; + + + /** + detector ID + */ + int detId; + + + /** + * parent multi detector + * */ + + multiSlsDetector *parentDet; + + /** + shared memeory ID + */ + int shmId; + + /** + socket for control commands + */ + MySocketTCP *controlSocket; + + /** + socket for emergency stop + */ + MySocketTCP *stopSocket; + + /** + socket for data acquisition + */ + MySocketTCP *dataSocket; + + + /** pointer to flat field coefficients */ + double *ffcoefficients; + /** pointer to flat field coefficient errors */ + double *fferrors; + + + /** pointer to detector module structures */ + sls_detector_module *detectorModules; + /** pointer to dac valuse */ + dacs_t *dacs; + /** pointer to adc valuse */ + dacs_t *adcs; + /** pointer to chip registers */ + int *chipregs; + /** pointer to channal registers */ + int *chanregs; + /** pointer to gain values */ + int *gain; + /** pointer to offset values */ + int *offset; + + receiverInterface *thisReceiver; + + + /** Initializes the shared memory + \param type is needed to define the size of the shared memory + \param id is the detector id needed to define the shared memory id + \return shm_id shared memory id + */ + int initSharedMemory(detectorType type=GENERIC, int id=0); + + /** + Initializes the thisDetector structure + \param type is needed to define the number of channels, chips, modules etc. + \sa sharedSlsDetector + */ + int initializeDetectorSize(detectorType type); + /** + Initializes the module structures in thisDetector if the detector did not exists before + */ + int initializeDetectorStructure(); + /** + send a sls_detector_channel structure over socket + */ + int sendChannel(sls_detector_channel*); + /** + send a sls_detector_chip structure over socket + */ + int sendChip(sls_detector_chip*); + /** + send a sls_detector_module structure over socket + */ + int sendModule(sls_detector_module*); + /** + receive a sls_detector_channel structure over socket + */ + int receiveChannel(sls_detector_channel*); + /** + receive a sls_detector_chip structure over socket + */ + int receiveChip(sls_detector_chip*); + /** + receive a sls_detector_module structure over socket + */ + int receiveModule(sls_detector_module*); + + /** Gets MAC from receiver and sets up UDP Connection */ + int setUDPConnection(); + + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetector/slsDetectorActions.cpp b/slsDetectorSoftware/slsDetector/slsDetectorActions.cpp new file mode 100644 index 000000000..5d0b77621 --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetectorActions.cpp @@ -0,0 +1,506 @@ +#include "slsDetectorActions.h" +#include +#include +#include +using namespace std; + + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param fname for script ("" disable but leaves script unchanged, "none" disables and overwrites) + \returns 0 if action disabled, >0 otherwise + */ +int slsDetectorActions::setAction(int iaction, string fname, string par) { + + int am; + + + if (iaction>=0 && iaction=0 && iaction=0 && iaction=0 && iaction=0 && iaction0 otherwise + */ +int slsDetectorActions::setScan(int iscan, string script, int nvalues, double *values, string par, int precision) { + if (iscan>=0 && iscan=0) { + if (nvalues==0) + scanMode[iscan]=noScan; + else { + nScanSteps[iscan]=nvalues; + if (nvalues>MAX_SCAN_STEPS) + nScanSteps[iscan]=MAX_SCAN_STEPS; + } + } + + if (values && scanMode[iscan]>0 ) { + for (int iv=0; iv=0) + scanPrecision[iscan]=precision; + + if (scanMode[iscan]>0){ + *actionMask |= 1<< (iscan+MAX_ACTIONS); + } else { + *actionMask &= ~(1 << (iscan+MAX_ACTIONS)); + } + + + + setTotalProgress(); + + + + + + + + + + + return scanMode[iscan]; + } else + return -1; + +} + +int slsDetectorActions::setScanScript(int iscan, string script) { + if (iscan>=0 && iscan0){ + *actionMask |= (1 << (iscan+MAX_ACTIONS)); + } else { + *actionMask &= ~(1 << (iscan+MAX_ACTIONS)); + } + + setTotalProgress(); + +#ifdef VERBOSE + cout << "Action mask is " << hex << actionMask << dec << endl; +#endif + return scanMode[iscan]; + } else + return -1; +} + + + +int slsDetectorActions::setScanParameter(int iscan, string par) { + + + if (iscan>=0 && iscan=0 && iscan=0) + scanPrecision[iscan]=precision; + return scanMode[iscan]; + } else + return -1; + +} + +int slsDetectorActions::setScanSteps(int iscan, int nvalues, double *values) { + + if (iscan>=0 && iscan=0) { + if (nvalues==0) + scanMode[iscan]=noScan; + else { + nScanSteps[iscan]=nvalues; + if (nvalues>MAX_SCAN_STEPS) + nScanSteps[iscan]=MAX_SCAN_STEPS; + } + } + + if (values) { + for (int iv=0; iv0){ + *actionMask |= (1 << (iscan+MAX_ACTIONS)); + } else { + *actionMask &= ~(1 << (iscan+MAX_ACTIONS)); + } + +#ifdef VERBOSE + cout << "Action mask is " << hex << actionMask << dec << endl; +#endif + setTotalProgress(); + + + + + return scanMode[iscan]; + + + } else + return -1; + + + + +} + + + + /** + returns scan script + \param iscan can be (0,1) + \returns scan script + */ +string slsDetectorActions::getScanScript(int iscan){ + if (iscan>=0 && iscan=0 && iscan=0 && iscan=0 && iscan=0 && iscanMAX_SCAN_LEVELS) + return -1; + + currentScanVariable[level]=getScanStep(level,istep); + currentScanIndex[level]=istep; + + switch(scanMode[level]) { + case energyScan: + setThresholdEnergy((int)currentScanVariable[level]); //energy scan + break; + case thresholdScan: + setDAC((dacs_t)currentScanVariable[level],THRESHOLD,0); // threshold scan + break; + case trimbitsScan: + trimbit=(int)currentScanVariable[level]; + if(getDetectorsType() == EIGER) + setAllTrimbits(trimbit); + else + setChannel((trimbit<<((int)TRIMBIT_OFF))|((int)COMPARATOR_ENABLE)); // trimbit scan + break; + case positionScan: + //check if channels are connected! + moveDetector(currentScanVariable[level]); + break; + case noScan: + currentScanVariable[level]=0; + break; + case scriptScan: + //Custom scan script level 1. The arguments are passed as nrun=n fn=filename var=v par=p" + sprintf(cmd,"%s nrun=%d fn=%s var=%f par=%s",getScanScript(level).c_str(),getFileIndex(),createFileName().c_str(),currentScanVariable[level],getScanParameter(level).c_str()); +#ifdef VERBOSE + cout << "Executing scan script "<< level << " " << cmd << endl; +#endif + system(cmd); + break; + default: + cout << "Scan mode unknown "<< level << " " < +#include + + + +#define MAX_SCAN_LEVELS 2 + +using namespace std; + +/** + +@short class implementing the script and scan utilities of the detectors + + +*/ + +class slsDetectorActions : public virtual slsDetectorBase +// : public virtual postProcessing +{ + public : + + enum {noScan, energyScan, thresholdScan, trimbitsScan, positionScan, scriptScan }; + + + /** default constructor */ + slsDetectorActions(){}; + + /** virtual destructor */ + virtual ~slsDetectorActions(){}; + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param fname for script ("" disable) + \param par for script + \returns 0 if action disabled, >0 otherwise + */ + int setAction(int iaction, string fname="", string par=""); + + /** + set action script + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param fname for script ("" disable) + \returns 0 if action disabled, >0 otherwise + */ + int setActionScript(int iaction, string fname=""); + + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param par for script + \returns 0 if action disabled, >0 otherwise + */ + int setActionParameter(int iaction, string par=""); + + + /** + returns action script + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action script + */ + string getActionScript(int iaction); + + /** + returns action parameter + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action parameter + */ + string getActionParameter(int iaction); + + /** + returns action mode + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action mode + */ + int getActionMode(int iaction); + + /** + set scan + \param index of the scan (0,1) + \param script fname for script ("" disables, "none" disables and overwrites current, "threshold" threshold scan, "trimbits", trimbits scan) + \param nvalues number of steps (0 disables, -1 leaves current value) + \param values pointer to steps (if NULL leaves current values) + \param par parameter for the scan script ("" leaves unchanged) + \param precision to write the scan varaible in the scan name (-1 unchanged) + \returns 0 is scan disabled, >0 otherwise + */ + int setScan(int index, string script="", int nvalues=-1, double *values=NULL, string par="", int precision=-1); + + /** set scan script + \param index of the scan (0,1) + \param script fname for script ("" disables, "none" disables and overwrites current, "threshold" threshold scan, "trimbits", trimbits scan) + \returns 0 is scan disabled, >0 otherwise + */ + int setScanScript(int index, string script=""); + /** set scan script parameter + \param index of the scan (0,1) + \param script parameter for scan + \returns 0 is scan disabled, >0 otherwise + */ + int setScanParameter(int index, string par=""); + /** set scan script parameter + \param index of the scan (0,1) + \param precision scan varaible precision to be printed in file name + \returns 0 is scan disabled, >0 otherwise + */ + int setScanPrecision(int index, int precision=-1); + + + /** set scan steps + \param index of the scan (0,1) + \param nvalues number of steps + \param values pointer to array of values + \returns 0 is scan disabled, >0 otherwise + */ + int setScanSteps(int index, int nvalues=-1, double *values=NULL); + + /** get scan step + \param index of the scan (0,1) + \param istep step number + \returns value of the scan variable + */ + double getScanStep(int index, int istep){if (index=0 && istep>=0 && istep=0) {startIndex=i; lastIndex=startIndex; nowIndex=startIndex;};return startIndex;}; + int setLastIndex(int i=-1){if (i>=0 && i>lastIndex) lastIndex=i; return lastIndex;}; + + + virtual double moveDetector(double)=0; + virtual double getDetectorPosition()=0; + + + + protected: + + + int executeScan(int level, int istep); + int executeAction(int level); + + + + /** action mask */ + int *actionMask; + /** array of action scripts */ + mystring *actionScript; + /** array of actionparameters */ + mystring *actionParameter; + + /** pointer to number of steps [2] */ + int *nScanSteps; + /** pointer to arrays of step values [2] */ + mysteps *scanSteps; + /** pointer to array of scan mode [2] */ + int *scanMode; + + /** POINTER TO ARRAY OF SCAN PRECISION [2] */ + int *scanPrecision; + + /** pointer to array of scan scripts [2] */ + mystring *scanScript; + + /** pointer to array of scan parameters [2] */ + mystring *scanParameter; + + + + + + + /** + current scan variable of the detector + */ + double currentScanVariable[MAX_SCAN_LEVELS]; + + /** + current scan variable index of the detector + */ + int currentScanIndex[MAX_SCAN_LEVELS]; + + + + + private: + int startIndex; + int lastIndex; + int nowIndex; + string fName; + + + + + + +}; +#endif diff --git a/slsDetectorSoftware/slsDetector/slsDetectorBase.h b/slsDetectorSoftware/slsDetector/slsDetectorBase.h new file mode 100644 index 000000000..62eb83006 --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetectorBase.h @@ -0,0 +1,757 @@ + +#ifndef SLS_DETECTOR_BASE_H +#define SLS_DETECTOR_BASE_H +/** + \mainpage Common C++ library for SLS detectors data acquisition + * + * \section intro_sec Introduction + + * \subsection mot_sec Motivation + Although the SLS detectors group delvelops several types of detectors (1/2D, counting/integrating etc.) it is common interest of the group to use a common platfor for data acquisition + \subsection arch_sec System Architecture + The architecture of the acquisitions system is intended as follows: + \li A socket server running on the detector (or more than one in some special cases) + \li C++ classes common to all detectors for client-server communication. These can be supplied to users as libraries and embedded also in acquisition systems which are not developed by the SLS + \li the possibility of using a Qt-based graphical user interface (with eventually root analisys capabilities) + \li the possibility of running all commands from command line. In order to ensure a fast operation of this so called "text client" the detector parameters should not be re-initialized everytime. For this reason a shared memory block is allocated where the main detector flags and parameters are stored + \li a Root library for data postprocessing and detector calibration (energy, angle). + + \section howto_sec How to use it + + The detectors can be simply operated by using the provided GUi or command line executable.
+ In case you need to embed the detector control e.g in the beamline control software, compile these classes using +
+ make package +
+ and link the shared library created to your software slsDetectorSoftware/bin/libSlsDetector.so +
+ The software can also be installed (with super-user rights)
+ make install +
+
+ Most methods of interest for the user are implemented in the ::slsDetectorBase interface class, but the classes to be implemented in the main program are either ::slsDetector (for single controller detectors) or ::multiSlsDetector (for multiple controllers, but can work also for single controllers). + + @author Anna Bergamaschi + @version 0.1alpha + +*/ + + + +/** + * + * + * + * @author Anna Bergamaschi + * @version 0.1alpha + */ + + +#include "sls_detector_defs.h" +#include "sls_receiver_defs.h" +#include "slsDetectorUsers.h" +#include "error_defs.h" + +#include + + +using namespace std; +/** + +@libdoc The slsDetectorBase contains also a set of purely virtual functions useful for the implementation of the derived classes + + +* @short This is the base class for all detector functionalities + +*/ + +//public virtual slsDetectorUsers, +class slsDetectorBase : public virtual slsDetectorDefs, public virtual errorDefs { + + public: + + /** default constructor */ + slsDetectorBase(){}; + + + /** virtual destructor */ + virtual ~slsDetectorBase(){}; + + /** returns the detector type + \param pos position in the multi detector structure (is -1 returns type of detector with id -1) + \returns type + */ + virtual detectorType getDetectorsType(int pos=-1)=0; + + string getDetectorDeveloper(){return string("PSI");}; + // protected: + + /** + set angular conversion + \param fname file with angular conversion constants ("" disable) + \returns 0 if angular conversion disabled, >0 otherwise + */ + virtual int setAngularConversionFile(string fname="")=0; + + + /** + pure virtual function + returns the angular conversion file + */ + virtual string getAngularConversionFile()=0; + + + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param fname for script ("" disable) + \returns 0 if action disabled, >0 otherwise + */ + virtual int setActionScript(int iaction, string fname="")=0; + + /** + set action + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript, MAX_ACTIONS} + \param par for script ("" disable) + \returns 0 if action disabled, >0 otherwise + */ + virtual int setActionParameter(int iaction, string par="")=0; + + /** + returns action script + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action script + */ + virtual string getActionScript(int iaction)=0; + + /** + returns action parameter + \param iaction can be enum {startScript, scriptBefore, headerBefore, headerAfter,scriptAfter, stopScript} + \returns action parameter + */ + virtual string getActionParameter(int iaction)=0; + + /** + set scan script + \param index is the scan index (0 or 1) + \param script fname for script ("" disable, "none" disables and overwrites current, "threshold" makes threshold scan, "trimbits" make trimbits scan, "energy" makes energy scan) + \returns 0 if scan disabled, >0 otherwise + */ + virtual int setScanScript(int index, string script="")=0; + + /** + set scan script parameter + \param index is the scan index (0 or 1) + \param spar parameter to be passed to the scan script with syntax par=spar + \returns 0 if scan disabled, >0 otherwise + */ + virtual int setScanParameter(int index, string spar="")=0; + + + /** set scan precision + \param index is the scan index (0 or 1) + \param precision number of decimals to use for the scan variable in the file name + \returns 0 if scan disabled, >0 otherwise */ + virtual int setScanPrecision(int index, int precision=-1)=0; + + /** + set scan steps (passed to the scan script as var=step) + \param index is the scan index (0 or 1) + \param nvalues is the number of steps + \param values array of steps + \returns 0 if scan disabled, >0 otherwise*/ + + virtual int setScanSteps(int index, int nvalues=-1, double *values=NULL)=0; + + /** + get scan script + \param index is the scan index (0 or 1) + \returns "none" if disables, "threshold" threshold scan, "trimbits" trimbits scan, "energy" energy scan or scan script name + */ + virtual string getScanScript(int index)=0; + + /** + get scan script + \param index is the scan index (0 or 1) + \returns scan script parameter + */ + virtual string getScanParameter(int index)=0; + + /** + get scan precision + \param index is the scan index (0 or 1) + \returns precision i.e. number of decimals to use for the scan variable in the file name + */ + virtual int getScanPrecision(int index)=0; + + /** + get scan steps + \param index is the scan index (0 or 1) + \param values pointer to array of values (must be allocated in advance) + \returns number of steps + */ + virtual int getScanSteps(int index, double *values=NULL)=0; + + + /** + Writes the configuration file -- will contain all the informations needed for the configuration (e.g. for a PSI detector caldir, settingsdir, angconv, badchannels etc.) + \param fname file name + \returns OK or FAIL + */ + virtual int writeConfigurationFile(string const fname)=0; + + + /** + Loads dark image or gain image to the detector + \param index can be DARK_IMAGE or GAIN_IMAGE + \param fname file name to load data from + \returns OK or FAIL + */ + virtual int loadImageToDetector(imageType index,string const fname)=0; + + /** + \returns number of positions + */ + virtual int getNumberOfPositions()=0;// {return 0;}; + + /** + \returns action mask + */ + virtual int getActionMask()=0;// {return 0;}; + /** + \param index scan level index + \returns current scan variable + */ + virtual double getCurrentScanVariable(int index)=0;// {return 0;}; + + /** + \returns current position index + */ + virtual int getCurrentPositionIndex()=0;// {return 0;}; + + /** + \returns total number of channels + */ + virtual int getTotalNumberOfChannels()=0; + + /** + \returns total number of channels for each dimension + */ + virtual int getTotalNumberOfChannels(dimension d)=0; + + /** generates file name without extension */ + virtual string createFileName()=0; + + + virtual void incrementProgress()=0; + virtual void setCurrentProgress(int i=0)=0; + virtual double getCurrentProgress()=0; + virtual void incrementFileIndex()=0; + virtual int setTotalProgress()=0; + + + virtual double* decodeData(int *datain, double *fdata=NULL)=0; + + + virtual string getCurrentFileName()=0; + + + virtual int getFileIndexFromFileName(string fname)=0; + + virtual int getIndicesFromFileName(string fname,int &index)=0; + + virtual double *convertAngles()=0; + /** + set rate correction + \param t dead time in ns - if 0 disable correction, if >0 set dead time to t, if <0 set deadtime to default dead time for current settings + \returns 0 if rate correction disabled, >0 otherwise + */ + virtual int setRateCorrection(double t=0)=0; + + /** + get rate correction + \param t reference for dead time + \returns 0 if rate correction disabled, >0 otherwise + */ + virtual int getRateCorrection(double &t)=0; + + /** + get rate correction + \returns 0 if rate correction disabled, >0 otherwise + */ + virtual int getRateCorrection()=0; + + virtual int setFlatFieldCorrection(string fname="")=0; + + int setFlatFieldCorrectionFile(string fname=""){return setFlatFieldCorrection(fname);}; + + /** + set/get dynamic range + \param i dynamic range (-1 get) + \returns current dynamic range + */ + virtual int setDynamicRange(int i=-1)=0; + // int setBitDepth(int i=-1){return setDynamicRange(i);}; + + /** + set/get the size of the detector + \param i number of modules + \param d dimension + \returns current number of modules in direction d + */ + virtual int setNumberOfModules(int i=-1, dimension d=X)=0; + + // int setDetectorSize(int x0=-1, int y0=-1, int nx=-1, int ny=-1){return setNumberOfModules(nx/getChansPerMod(0),X);}; + + // int getDetectorSize(int &x0, int &y0, int &nx, int &ny){x0=0; nx=setNumberOfModules(-1,X)*getChansPerMod(0); return nx;}; + + virtual int getMaxNumberOfModules(dimension d=X)=0; // + // int getMaximumDetectorSize(int &nx, int &ny){nx=getMaxNumberOfModules(X)*getChansPerMod(0); ny=1; return nx;}; + + + /** Locks/Unlocks the connection to the server + /param lock sets (1), usets (0), gets (-1) the lock + /returns lock status of the server + */ + virtual int lockServer(int i=-1)=0; + + + + /** performs a complete acquisition including scansand data processing + moves the detector to next position
+ starts and reads the detector
+ reads the IC (if required)
+ reads the encoder (iof required for angualr conversion)
+ processes the data (flat field, rate, angular conversion and merging ::processData()) + \param delflag 0 leaves the data in the final data queue (default is 1) + \returns OK or FAIL depending on if it already started + */ + virtual int acquire(int delflag=1)=0; + + int startMeasurement(){acquire(0); return OK;}; + + /** + asks and receives a data frame from the detector, writes it to disk and processes the data + \returns pointer to the data or NULL (unused!!!). + */ + virtual int* readFrame()=0; + + + /** + get detector ids/versions for module=0 + \param mode which id/version has to be read + \param imod module number for module serial number + \returns id + */ + virtual int64_t getId(idMode mode, int imod=0)=0; + int64_t getModuleFirmwareVersion(){return getId(MODULE_FIRMWARE_VERSION,-1);}; + int64_t getModuleSerialNumber(int imod=-1){return getId(MODULE_SERIAL_NUMBER,imod);}; + int64_t getDetectorFirmwareVersion(){return getId(DETECTOR_FIRMWARE_VERSION,-1);}; + int64_t getDetectorSerialNumber(){return getId(DETECTOR_SERIAL_NUMBER,-1);}; + int64_t getDetectorSoftwareVersion(){return getId(DETECTOR_SOFTWARE_VERSION,-1);}; + int64_t getThisSoftwareVersion(){return getId(THIS_SOFTWARE_VERSION,-1);}; + + /** + start detector acquisition + \returns OK/FAIL + */ + virtual int startAcquisition()=0; + /** + stop detector acquisition + \returns OK/FAIL + */ + virtual int stopAcquisition()=0; + int stopMeasurement(){return stopAcquisition();}; + virtual int getChansPerMod(int imod=0)=0; + + /** + set/get timer value + \param index timer index + \param t time in ns or number of...(e.g. frames, gates, probes) + \returns timer set value in ns or number of...(e.g. frames, gates, probes) + */ + virtual int64_t setTimer(timerIndex index, int64_t t=-1)=0; + int64_t setExposureTime(int64_t t=-1){return setTimer(ACQUISITION_TIME,t);}; + int64_t setSubFrameExposureTime(int64_t t=-1){return setTimer(SUBFRAME_ACQUISITION_TIME,t);}; + int64_t setExposurePeriod(int64_t t=-1){return setTimer(FRAME_PERIOD,t);}; + int64_t setDelayAfterTrigger(int64_t t=-1){return setTimer(DELAY_AFTER_TRIGGER,t);}; + int64_t setNumberOfGates(int64_t t=-1){return setTimer(GATES_NUMBER,t);}; + int64_t setNumberOfFrames(int64_t t=-1){return setTimer(FRAME_NUMBER,t);}; + int64_t setNumberOfCycles(int64_t t=-1){return setTimer(CYCLES_NUMBER,t);}; + + /////////////////////////////////////////////////////////////////////////////////////////// + /** + @short get run status + \returns status mask + */ + virtual runStatus getRunStatus()=0; + int getDetectorStatus() {return (int)getRunStatus();}; + + + /** @short sets the onlineFlag + \param online can be: -1 returns wether the detector is in online (1) or offline (0) state; 0 detector in offline state; 1 detector in online state + \returns 0 (offline) or 1 (online) + */ + virtual int setOnline(int const online=-1)=0; + + /** @short activates the detector (detector specific) + \param enable can be: -1 returns wether the detector is in active (1) or inactive (0) state + \returns 0 (inactive) or 1 (active) + */ + virtual int activate(int const enable=GET_ONLINE_FLAG)=0; + + + /** + @short set detector settings + \param isettings settings index (-1 gets) + \returns current settings + */ + virtual detectorSettings setSettings(detectorSettings isettings, int imod=-1)=0; + int setSettings(int isettings){return (int)setSettings((detectorSettings)isettings,-1);}; + + virtual detectorSettings getSettings(int imod=-1)=0; + /** + get threshold energy + \param imod module number (-1 all) + \returns current threshold value for imod in ev (-1 failed) + */ + virtual int getThresholdEnergy(int imod)=0; + int getThresholdEnergy(){return getThresholdEnergy(-1);}; + + /** + set/get the external communication mode + + obsolete \sa setExternalSignalFlags + \param pol value to be set \sa externalCommunicationMode + \returns current external communication mode + */ + virtual externalCommunicationMode setExternalCommunicationMode(externalCommunicationMode pol=GET_EXTERNAL_COMMUNICATION_MODE)=0; + int setTimingMode(int i=-1){return slsDetectorUsers::getTimingMode( externalCommunicationType( setExternalCommunicationMode(externalCommunicationType( slsDetectorUsers::getTimingMode(i) ) ) ) );}; + + virtual int setThresholdEnergy(int e_eV, int imod, detectorSettings isettings=GET_SETTINGS)=0; + int setThresholdEnergy(int e_eV){return setThresholdEnergy(e_eV,-1);}; + + + // int getBeamEnergy(){return 2*getThresholdEnergy();}; + //int setBeamEnergy(int e){return 2*setThresholdEnergy(e/2);}; + + + /** + Prints receiver configuration + \returns OK or FAIL + */ + virtual int printReceiverConfiguration()=0; + + /** + Reads the configuration file fname + \param fname file name + \returns OK or FAIL + */ + virtual int readConfigurationFile(string const fname)=0; + + virtual int dumpDetectorSetup(string const fname, int level)=0; + int dumpDetectorSetup(string const fname){return dumpDetectorSetup(fname,0);}; + virtual int retrieveDetectorSetup(string const fname, int level)=0; + int retrieveDetectorSetup(string const fname){return retrieveDetectorSetup(fname,0);}; + /** + @short + \returns the default output file index + */ + virtual int getFileIndex()=0; + + /** + @short sets the default output file index + \param i file index + \returns the default output file index + */ + virtual int setFileIndex(int i)=0; + + + //receiver + /** + calls setReceiverTCPSocket if online and sets the flag + */ + virtual int setReceiverOnline(int const online=GET_ONLINE_FLAG)=0; + + /** Starts the listening mode of receiver + \returns OK or FAIL + */ + virtual int startReceiver()=0; + + /** Stops the listening mode of receiver + \returns OK or FAIL + */ + virtual int stopReceiver()=0; + + /** gets the status of the listening mode of receiver + \returns status + */ + virtual runStatus getReceiverStatus()=0; + + /** gets the number of frames caught by receiver + \returns number of frames caught by receiver + */ + virtual int getFramesCaughtByReceiver()=0; + + /** + \returns current frame index of receiver + */ + virtual int getReceiverCurrentFrameIndex()=0; + + /** Locks/Unlocks the connection to the receiver + /param lock sets (1), usets (0), gets (-1) the lock + /returns lock status of the receiver + */ + virtual int lockReceiver(int lock=-1)=0; + + + /** + * Reads a frame from receiver + * @param fName file name of current frame() + * @param acquisitionIndex current acquisition index + * @param frameIndex current frame index (for each scan) + * @param subFrameIndex current sub frame index (for 32 bit mode for eiger) + /returns a frame read from recever + */ + virtual int* readFrameFromReceiver(char* fName, int &acquisitionIndex, int &frameIndex, int &subFrameIndex)=0; + + + /** Sets the read receiver frequency + if Receiver read upon gui request, readRxrFrequency=0, + else every nth frame to be sent to gui + @param getFromReceiver is 1 if it should ask the receiver, + 0 if it can get it from multislsdetecter + @param i is the receiver read frequency + /returns read receiver frequency + */ + virtual int setReadReceiverFrequency(int getFromReceiver, int i=-1)=0; + + /** Sets the receiver to start any readout remaining in the fifo and + * change status to transmitting. + * The status changes to run_finished when fifo is empty + */ + virtual runStatus startReceiverReadout()=0; + + + /** returns detector type string from detector type index + \param t string can be Mythen, Pilatus, Eiger, Gotthard, Agipd, Unknown + \returns MYTHEN, PILATUS, EIGER, GOTTHARD, AGIPD, MÖNCH, GENERIC + */ + static string getDetectorType(detectorType t){\ + switch (t) {\ + case MYTHEN: return string("Mythen"); \ + case PILATUS: return string("Pilatus"); \ + case EIGER: return string("Eiger"); \ + case GOTTHARD: return string("Gotthard"); \ + case AGIPD: return string("Agipd"); \ + case MOENCH: return string("Moench"); \ + case JUNGFRAU: return string("Jungfrau"); \ + case JUNGFRAUCTB: return string("JungfrauCTB"); \ + case PROPIX: return string("Propix"); \ + default: return string("Unknown"); \ + }}; + + /** returns detector type index from detector type string + \param type can be MYTHEN, PILATUS, EIGER, GOTTHARD, AGIPD, GENERIC + \returns Mythen, Pilatus, Eiger, Gotthard, Agipd, Mönch, Unknown + */ + static detectorType getDetectorType(string const type){\ + if (type=="Mythen") return MYTHEN;\ + if (type=="Pilatus") return PILATUS; \ + if (type=="Eiger") return EIGER; \ + if (type=="Gotthard") return GOTTHARD; \ + if (type=="Agipd") return AGIPD; \ + if (type=="Moench") return MOENCH; \ + if (type=="Jungfrau") return JUNGFRAU; \ + if (type=="JungfrauCTB") return JUNGFRAUCTB; \ + if (type=="Propix") return PROPIX; \ + return GENERIC;}; + + + + /** returns synchronization type index from string + \param type can be none, gating, trigger, complementary + \returns ONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS + */ + static synchronizationMode getSyncType(string const type){\ + if (type=="none") return NO_SYNCHRONIZATION;\ + if (type=="gating") return MASTER_GATES;\ + if (type=="trigger") return MASTER_TRIGGERS; \ + if (type=="complementary") return SLAVE_STARTS_WHEN_MASTER_STOPS; \ + return GET_SYNCHRONIZATION_MODE; \ + }; + + /** returns synchronization type string from index + \param s can be NONE, MASTER_GATES, MASTER_TRIGGERS, SLAVE_STARTS_WHEN_MASTER_STOPS + \returns none, gating, trigger, complementary, unknown + */ + static string getSyncType(synchronizationMode s ){\ + switch(s) { \ + case NO_SYNCHRONIZATION: return string("none"); \ + case MASTER_GATES: return string("gating"); \ + case MASTER_TRIGGERS: return string("trigger"); \ + case SLAVE_STARTS_WHEN_MASTER_STOPS: return string("complementary"); \ + default: return string("unknown"); \ + }}; + + + + /** returns string from external signal type index + \param f can be SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW, TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE, RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, =TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE, RO_TRIGGER_OUT_FALLING_EDGE, OUTPUT_LOW, OUTPUT_HIGH, MASTER_SLAVE_SYNCHRONIZATION, GET_EXTERNAL_SIGNAL_FLAG + \returns string off, gate_in_active_high, gate_in_active_low, trigger_in_rising_edge, trigger_in_falling_edge, ro_trigger_in_rising_edge, ro_trigger_in_falling_edge, gate_out_active_high, gate_out_active_low, trigger_out_rising_edge, trigger_out_falling_edge, ro_trigger_out_rising_edge, ro_trigger_out_falling_edge, gnd, vcc, sync, unknown + */ + static string externalSignalType(externalSignalFlag f){\ + switch(f) { \ + case SIGNAL_OFF: return string( "off"); \ + case GATE_IN_ACTIVE_HIGH: return string( "gate_in_active_high"); \ + case GATE_IN_ACTIVE_LOW: return string( "gate_in_active_low"); \ + case TRIGGER_IN_RISING_EDGE: return string( "trigger_in_rising_edge"); \ + case TRIGGER_IN_FALLING_EDGE: return string( "trigger_in_falling_edge"); \ + case RO_TRIGGER_IN_RISING_EDGE: return string( "ro_trigger_in_rising_edge"); \ + case RO_TRIGGER_IN_FALLING_EDGE: return string( "ro_trigger_in_falling_edge"); \ + case GATE_OUT_ACTIVE_HIGH: return string( "gate_out_active_high"); \ + case GATE_OUT_ACTIVE_LOW: return string( "gate_out_active_low"); \ + case TRIGGER_OUT_RISING_EDGE: return string( "trigger_out_rising_edge"); \ + case TRIGGER_OUT_FALLING_EDGE: return string( "trigger_out_falling_edge"); \ + case RO_TRIGGER_OUT_RISING_EDGE: return string( "ro_trigger_out_rising_edge"); \ + case RO_TRIGGER_OUT_FALLING_EDGE: return string( "ro_trigger_out_falling_edge"); \ + case MASTER_SLAVE_SYNCHRONIZATION: return string("sync"); \ + case OUTPUT_LOW: return string("gnd"); \ + case OUTPUT_HIGH: return string("vcc"); \ + default: return string( "unknown"); \ + } }; + + + + + /** returns external signal type index from string + \param sval off, gate_in_active_high, gate_in_active_low, trigger_in_rising_edge, trigger_in_falling_edge, ro_trigger_in_rising_edge, ro_trigger_in_falling_edge, gate_out_active_high, gate_out_active_low, trigger_out_rising_edge, trigger_out_falling_edge, ro_trigger_out_rising_edge, ro_trigger_out_falling_edge, gnd, vcc, sync, unknown + \returns can be SIGNAL_OFF, GATE_IN_ACTIVE_HIGH, GATE_IN_ACTIVE_LOW, TRIGGER_IN_RISING_EDGE, TRIGGER_IN_FALLING_EDGE, RO_TRIGGER_IN_RISING_EDGE, RO_TRIGGER_IN_FALLING_EDGE, GATE_OUT_ACTIVE_HIGH, GATE_OUT_ACTIVE_LOW, TRIGGER_OUT_RISING_EDGE, TRIGGER_OUT_FALLING_EDGE, RO_TRIGGER_OUT_RISING_EDGE, RO_TRIGGER_OUT_FALLING_EDGE, OUTPUT_LOW, OUTPUT_HIGH, MASTER_SLAVE_SYNCHRONIZATION, GET_EXTERNAL_SIGNAL_FLAG (if unknown) + */ + + static externalSignalFlag externalSignalType(string sval){\ + if (sval=="off") return SIGNAL_OFF;\ + if (sval=="gate_in_active_high") return GATE_IN_ACTIVE_HIGH; \ + if (sval=="gate_in_active_low") return GATE_IN_ACTIVE_LOW;\ + if (sval=="trigger_in_rising_edge") return TRIGGER_IN_RISING_EDGE;\ + if (sval=="trigger_in_falling_edge") return TRIGGER_IN_FALLING_EDGE;\ + if (sval=="ro_trigger_in_rising_edge") return RO_TRIGGER_IN_RISING_EDGE;\ + if (sval=="ro_trigger_in_falling_edge") return RO_TRIGGER_IN_FALLING_EDGE;\ + if (sval=="gate_out_active_high") return GATE_OUT_ACTIVE_HIGH;\ + if (sval=="gate_out_active_low") return GATE_OUT_ACTIVE_LOW;\ + if (sval=="trigger_out_rising_edge") return TRIGGER_OUT_RISING_EDGE;\ + if (sval=="trigger_out_falling_edge") return TRIGGER_OUT_FALLING_EDGE;\ + if (sval=="ro_trigger_out_rising_edge") return RO_TRIGGER_OUT_RISING_EDGE;\ + if (sval=="ro_trigger_out_falling_edge") return RO_TRIGGER_OUT_FALLING_EDGE;\ + if (sval=="sync") return MASTER_SLAVE_SYNCHRONIZATION;\ + if (sval=="gnd") return OUTPUT_LOW;\ + if (sval=="vcc") return OUTPUT_HIGH;\ + return GET_EXTERNAL_SIGNAL_FLAG ;}; + + /** returns detector settings string from index + \param s can be STANDARD, FAST, HIGHGAIN, DYNAMICGAIN, LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN, LOWNOISE, + DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2, GET_SETTINGS + \returns standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain, lownoise, + dynamichg0, fixgain1, fixgain2, forceswitchg1, forceswitchg2, verylowgain, undefined + */ + static string getDetectorSettings(detectorSettings s){\ + switch(s) { \ + case STANDARD: return string("standard"); \ + case FAST: return string("fast"); \ + case HIGHGAIN: return string("highgain"); \ + case DYNAMICGAIN: return string("dynamicgain"); \ + case LOWGAIN: return string("lowgain"); \ + case MEDIUMGAIN: return string("mediumgain"); \ + case VERYHIGHGAIN: return string("veryhighgain"); \ + case LOWNOISE: return string("lownoise"); \ + case DYNAMICHG0: return string("dynamichg0"); \ + case FIXGAIN1: return string("fixgain1"); \ + case FIXGAIN2: return string("fixgain2"); \ + case FORCESWITCHG1: return string("forceswitchg1");\ + case FORCESWITCHG2: return string("forceswitchg2");\ + case VERYLOWGAIN: return string("verylowgain");\ + default: return string("undefined"); \ + }}; + + /** returns detector settings string from index + \param s can be standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain, lownoise, + dynamichg0, fixgain1, fixgain2, forceswitchg1, forceswitchg2, undefined + \returns setting index STANDARD, FAST, HIGHGAIN, DYNAMICGAIN, LOWGAIN, MEDIUMGAIN, VERYHIGHGAIN,LOWNOISE, + DYNAMICHG0, FIXGAIN1, FIXGAIN2, FORCESWITCHG1, FORCESWITCHG2, VERYLOWGAIN, GET_SETTINGS + */ + + static detectorSettings getDetectorSettings(string s){ \ + if (s=="standard") return STANDARD; \ + if (s=="fast") return FAST; \ + if (s=="highgain") return HIGHGAIN; \ + if (s=="dynamicgain") return DYNAMICGAIN; \ + if (s=="lowgain") return LOWGAIN; \ + if (s=="mediumgain") return MEDIUMGAIN; \ + if (s=="veryhighgain") return VERYHIGHGAIN; \ + if (s=="lownoise") return LOWNOISE; \ + if (s=="dynamichg0") return DYNAMICHG0; \ + if (s=="fixgain1") return FIXGAIN1; \ + if (s=="fixgain2") return FIXGAIN2; \ + if (s=="forceswitchg1") return FORCESWITCHG1; \ + if (s=="forceswitchg2") return FORCESWITCHG2; \ + if (s=="verylowgain") return VERYLOWGAIN; \ + return GET_SETTINGS; \ + }; + + + /** + returns external communication mode string from index + \param f can be AUTO_TIMING, TRIGGER_EXPOSURE, TRIGGER_READOUT, GATE_FIX_NUMBER, GATE_WITH_START_TRIGGER, BURST_TRIGGER, GET_EXTERNAL_COMMUNICATION_MODE + \returns auto, trigger, ro_trigger, gating, triggered_gating, unknown + */ + + static string externalCommunicationType(externalCommunicationMode f){ \ + switch(f) { \ + case AUTO_TIMING: return string( "auto"); \ + case TRIGGER_EXPOSURE: return string("trigger"); \ + case TRIGGER_READOUT: return string("ro_trigger"); \ + case GATE_FIX_NUMBER: return string("gating"); \ + case GATE_WITH_START_TRIGGER: return string("triggered_gating"); \ + case BURST_TRIGGER: return string("burst_trigger"); \ + default: return string( "unknown"); \ + } }; + + + + /** + returns external communication mode index from string + \param sval can be auto, trigger, ro_trigger, gating, triggered_gating + \returns AUTO_TIMING, TRIGGER_EXPOSURE, TRIGGER_READOUT, GATE_FIX_NUMBER, GATE_WITH_START_TRIGGER, BURST_TRIGGER, GET_EXTERNAL_COMMUNICATION_MODE + */ + + static externalCommunicationMode externalCommunicationType(string sval){\ + if (sval=="auto") return AUTO_TIMING;\ + if (sval=="trigger") return TRIGGER_EXPOSURE; \ + if (sval=="ro_trigger") return TRIGGER_READOUT;\ + if (sval=="gating") return GATE_FIX_NUMBER;\ + if (sval=="triggered_gating") return GATE_WITH_START_TRIGGER;\ + if (sval=="burst_trigger") return BURST_TRIGGER;\ + return GET_EXTERNAL_COMMUNICATION_MODE; \ + }; + + /** returns string from run status index + \param s can be ERROR, WAITING, RUNNING, TRANSMITTING, RUN_FINISHED + \returns string error, waiting, running, data, finished + */ + static string runStatusType(runStatus s){\ + switch (s) { \ + case ERROR: return string("error"); \ + case WAITING: return string("waiting"); \ + case RUNNING: return string("running");\ + case TRANSMITTING: return string("data"); \ + case RUN_FINISHED: return string("finished"); \ + default: return string("idle"); \ + }}; + + + +}; + + +#endif diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp new file mode 100644 index 000000000..496eb1c4a --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.cpp @@ -0,0 +1,5183 @@ +#include "slsDetectorCommand.h" + +#include +#include +#include +#include + +#include + +slsDetectorCommand::slsDetectorCommand(slsDetectorUtils *det) { + + myDet=det; + + int i=0; + + cmd=string("none"); + + /* Acquisition and status commands */ + + descrToFuncMap[i].m_pFuncName="test"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdUnderDevelopment; + i++; + + descrToFuncMap[i].m_pFuncName="acquire"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAcquire; + i++; + + descrToFuncMap[i].m_pFuncName="data"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdData; + i++; + + descrToFuncMap[i].m_pFuncName="frame"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdFrame; + i++; + + descrToFuncMap[i].m_pFuncName="status"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdStatus; + i++; + + + /* Detector structure configuration and debugging commands */ + + + descrToFuncMap[i].m_pFuncName="free";//OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdFree; + i++; + + + descrToFuncMap[i].m_pFuncName="add";//OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdd; + i++; + + descrToFuncMap[i].m_pFuncName="remove";//OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRemove; + i++; + + + descrToFuncMap[i].m_pFuncName="type"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname; + i++; + + descrToFuncMap[i].m_pFuncName="hostname"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHostname; + i++; + + descrToFuncMap[i].m_pFuncName="id"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdId; + i++; + + descrToFuncMap[i].m_pFuncName="master"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdMaster; + i++; + + descrToFuncMap[i].m_pFuncName="sync"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSync; + i++; + + descrToFuncMap[i].m_pFuncName="help";//OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdHelp; + i++; + + descrToFuncMap[i].m_pFuncName="exitserver";//OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdExitServer; + i++; + + descrToFuncMap[i].m_pFuncName="exitreceiver";//OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdExitServer; + i++; + + + /* data processing commands */ + + + descrToFuncMap[i].m_pFuncName="flatfield"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdFlatField; + i++; + + descrToFuncMap[i].m_pFuncName="ffdir"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdFlatField; + i++; + + descrToFuncMap[i].m_pFuncName="ratecorr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRateCorr; + i++; + + descrToFuncMap[i].m_pFuncName="badchannels"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdBadChannels; + i++; + + descrToFuncMap[i].m_pFuncName="angconv"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + descrToFuncMap[i].m_pFuncName="globaloff"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + descrToFuncMap[i].m_pFuncName="fineoff"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + descrToFuncMap[i].m_pFuncName="binsize" ;// + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + descrToFuncMap[i].m_pFuncName="angdir" ;// + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + + descrToFuncMap[i].m_pFuncName="moveflag" ;// + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + descrToFuncMap[i].m_pFuncName="samplex" ;// + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + + descrToFuncMap[i].m_pFuncName="sampley" ;// + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAngConv; + i++; + + + + descrToFuncMap[i].m_pFuncName="threaded"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdThreaded; + i++; + + descrToFuncMap[i].m_pFuncName="darkimage"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdImage; + i++; + + descrToFuncMap[i].m_pFuncName="gainimage"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdImage; + i++; + + descrToFuncMap[i].m_pFuncName="readctr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdCounter; + i++; + + descrToFuncMap[i].m_pFuncName="resetctr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdCounter; + i++; + + descrToFuncMap[i].m_pFuncName="resmat"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdCounter; + i++; + + /* trim/cal directories */ + descrToFuncMap[i].m_pFuncName="trimdir"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettingsDir; + i++; + + descrToFuncMap[i].m_pFuncName="settingsdir"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettingsDir; + i++; + + descrToFuncMap[i].m_pFuncName="caldir"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdCalDir; + i++; + + descrToFuncMap[i].m_pFuncName="trimen"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdUnderDevelopment; + i++; + + + /* file name */ + descrToFuncMap[i].m_pFuncName="outdir"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdOutDir; + i++; + + descrToFuncMap[i].m_pFuncName="fname"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdFileName; + i++; + + descrToFuncMap[i].m_pFuncName="index"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdFileIndex; + i++; + + + descrToFuncMap[i].m_pFuncName="online"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdOnline; + i++; + + descrToFuncMap[i].m_pFuncName="checkonline"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdOnline; + i++; + + descrToFuncMap[i].m_pFuncName="activate"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdOnline; + i++; + + descrToFuncMap[i].m_pFuncName="enablefwrite"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdEnablefwrite; + i++; + + descrToFuncMap[i].m_pFuncName="overwrite"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdOverwrite; + i++; + + descrToFuncMap[i].m_pFuncName="currentfname"; //OK + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdFileName; + i++; + + /* Acquisition actions */ + + descrToFuncMap[i].m_pFuncName="positions"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPositions; + i++; + + descrToFuncMap[i].m_pFuncName="startscript"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="startscriptpar"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="stopscript"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="stopscriptpar"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="scriptbefore"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="scriptbeforepar"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="scriptafter"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="scriptafterpar"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="headerafter"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="headerafterpar"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="encallog"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="angcallog"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + + + + + + + + descrToFuncMap[i].m_pFuncName="headerbefore"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="headerbeforepar"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScripts; + i++; + + descrToFuncMap[i].m_pFuncName="scan0script"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan0par"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan0prec"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan0steps"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan0range"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan1script"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan1par"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan1prec"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan1steps"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + descrToFuncMap[i].m_pFuncName="scan1range"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdScans; + i++; + + + /* communication configuration */ + + descrToFuncMap[i].m_pFuncName="rx_hostname"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="rx_udpip"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="rx_udpmac"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="rx_udpport"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="rx_udpport2"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="detectormac"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="detectorip"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="txndelay_left"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="txndelay_right"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="txndelay_frame"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="flowcontrol_10g"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdNetworkParameter; + i++; + + descrToFuncMap[i].m_pFuncName="configuremac"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdConfigureMac; + i++; + + descrToFuncMap[i].m_pFuncName="rx_tcpport"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPort; + i++; + + descrToFuncMap[i].m_pFuncName="port"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPort; + i++; + + descrToFuncMap[i].m_pFuncName="stopport"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPort; + i++; + + descrToFuncMap[i].m_pFuncName="lock"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdLock; + i++; + + descrToFuncMap[i].m_pFuncName="lastclient"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdLastClient; + i++; + + + /* detector and data size */ + descrToFuncMap[i].m_pFuncName="nmod"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize; + i++; + + descrToFuncMap[i].m_pFuncName="maxmod"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize; + i++; + + descrToFuncMap[i].m_pFuncName="dr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize; + i++; + + descrToFuncMap[i].m_pFuncName="roi"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize; + i++; + + descrToFuncMap[i].m_pFuncName="detsizechan"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize; + i++; + + descrToFuncMap[i].m_pFuncName="roimask"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDetectorSize; + i++; + + + + /* flags */ + + descrToFuncMap[i].m_pFuncName="flags"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; + i++; + + descrToFuncMap[i].m_pFuncName="extsig"; /* find command! */ + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdAdvanced; + i++; + + /* versions/ serial numbers getId */ + + descrToFuncMap[i].m_pFuncName="moduleversion"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + i++; + + descrToFuncMap[i].m_pFuncName="detectornumber"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + i++; + + descrToFuncMap[i].m_pFuncName="modulenumber"; /* find command! */ + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + i++; + + descrToFuncMap[i].m_pFuncName="detectorversion"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + i++; + + descrToFuncMap[i].m_pFuncName="softwareversion"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + i++; + + descrToFuncMap[i].m_pFuncName="thisversion"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + i++; + + descrToFuncMap[i].m_pFuncName="receiverversion"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSN; + i++; + + + /* digital test and debugging */ + + descrToFuncMap[i].m_pFuncName="digitest"; // /* find command! */ + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDigiTest; + i++; + + descrToFuncMap[i].m_pFuncName="bustest"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDigiTest; + i++; + + descrToFuncMap[i].m_pFuncName="digibittest"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDigiTest; + i++; + + descrToFuncMap[i].m_pFuncName="reg"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRegister; + i++; + + descrToFuncMap[i].m_pFuncName="adcreg"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRegister; + i++; + + descrToFuncMap[i].m_pFuncName="setbit"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRegister; + i++; + + descrToFuncMap[i].m_pFuncName="clearbit"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRegister; + i++; + + descrToFuncMap[i].m_pFuncName="getbit"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdRegister; + i++; + + + + + + + + + + + /* settings, threshold */ + + descrToFuncMap[i].m_pFuncName="settings"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettings; + i++; + + descrToFuncMap[i].m_pFuncName="threshold"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettings; + i++; + + descrToFuncMap[i].m_pFuncName="trimbits"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettings; + i++; + + descrToFuncMap[i].m_pFuncName="trim"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettings; + i++; + + descrToFuncMap[i].m_pFuncName="trimval"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettings; + i++; + + descrToFuncMap[i].m_pFuncName="pedestal"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSettings; + i++; + + + + /* pots */ + + descrToFuncMap[i].m_pFuncName="vthreshold"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcalibration"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vtrimbit"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vpreamp"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vshaper1"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vshaper2"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vhighvoltage"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vapower"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vddpower"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vshpower"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="viopower"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vref_ds"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcascn_pb"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcascp_pb"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vout_cm"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcasc_out"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vin_cm"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vref_comp"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="ib_test_c"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="ib_test_c"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac0"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac1"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac2"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac3"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac4"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac5"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac6"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="dac7"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vsvp"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vsvn"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vtr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vrf"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vrs"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vtgstv"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcmp_ll"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcmp_lr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcall"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcmp_rl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcmp_rr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="rxb_rb"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="rxb_lb"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcp"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vcn"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="vis"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="iodelay"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + + descrToFuncMap[i].m_pFuncName="dac"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + + + descrToFuncMap[i].m_pFuncName="adcvpp"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + + descrToFuncMap[i].m_pFuncName="v_a"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="v_b"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="v_c"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="v_d"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="v_io"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + descrToFuncMap[i].m_pFuncName="v_chip"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdDAC; + i++; + + /* r/w timers */ + + descrToFuncMap[i].m_pFuncName="temp_adc"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_fpga"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_fpgaext"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_10ge"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_dcdc"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_sodl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_sodr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_fpgafl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + descrToFuncMap[i].m_pFuncName="temp_fpgafr"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdADC; + i++; + + + /* r/w timers */ + + descrToFuncMap[i].m_pFuncName="timing"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTiming; + i++; + + descrToFuncMap[i].m_pFuncName="exptime"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + descrToFuncMap[i].m_pFuncName="subexptime"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + descrToFuncMap[i].m_pFuncName="period"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + descrToFuncMap[i].m_pFuncName="delay"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + descrToFuncMap[i].m_pFuncName="gates"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + descrToFuncMap[i].m_pFuncName="frames"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + descrToFuncMap[i].m_pFuncName="cycles"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + descrToFuncMap[i].m_pFuncName="probes"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + + descrToFuncMap[i].m_pFuncName="measurements"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + i++; + + /* read only timers */ + + descrToFuncMap[i].m_pFuncName="exptimel"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + descrToFuncMap[i].m_pFuncName="periodl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + descrToFuncMap[i].m_pFuncName="delayl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + descrToFuncMap[i].m_pFuncName="gatesl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + descrToFuncMap[i].m_pFuncName="framesl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + descrToFuncMap[i].m_pFuncName="cyclesl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + // descrToFuncMap[i].m_pFuncName="progress"; + // descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimer; + // i++; + + descrToFuncMap[i].m_pFuncName="now"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + descrToFuncMap[i].m_pFuncName="timestamp"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + descrToFuncMap[i].m_pFuncName="nframes"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdTimeLeft; + i++; + + /* speed */ + + descrToFuncMap[i].m_pFuncName="clkdivider"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="setlength"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="waitstates"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="totdivider"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="totdutycycle"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="phasestep"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="oversampling"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="adcclk"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + descrToFuncMap[i].m_pFuncName="adcphase"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + + descrToFuncMap[i].m_pFuncName="adcpipeline"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdSpeed; + i++; + + + + /* settings dump/retrieve */ + descrToFuncMap[i].m_pFuncName="config"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdConfiguration; + i++; + + descrToFuncMap[i].m_pFuncName="rx_printconfig"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdConfiguration; + i++; + + descrToFuncMap[i].m_pFuncName="parameters"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdConfiguration; + i++; + + descrToFuncMap[i].m_pFuncName="setup"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdConfiguration; + i++; + + + /* receiver functions */ + descrToFuncMap[i].m_pFuncName="receiver"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + descrToFuncMap[i].m_pFuncName="r_online"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdOnline; + i++; + + descrToFuncMap[i].m_pFuncName="r_checkonline"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdOnline; + i++; + + descrToFuncMap[i].m_pFuncName="framescaught"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + descrToFuncMap[i].m_pFuncName="resetframescaught"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + descrToFuncMap[i].m_pFuncName="frameindex"; + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + descrToFuncMap[i].m_pFuncName="r_lock"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdLock; + i++; + + descrToFuncMap[i].m_pFuncName="r_lastclient"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdLastClient; + i++; + + descrToFuncMap[i].m_pFuncName="r_readfreq"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + descrToFuncMap[i].m_pFuncName="r_compression"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + descrToFuncMap[i].m_pFuncName="tengiga"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + descrToFuncMap[i].m_pFuncName="rx_fifodepth"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdReceiver; + i++; + + /* pattern generator */ + + + descrToFuncMap[i].m_pFuncName="adcinvert"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + descrToFuncMap[i].m_pFuncName="adcdisable"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + descrToFuncMap[i].m_pFuncName="pattern"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patword"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patioctrl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patclkctrl"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patlimits"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + descrToFuncMap[i].m_pFuncName="patloop0"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patnloop0"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patwait0"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patwaittime0"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patloop1"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patnloop1"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patwait1"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patwaittime1"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patloop2"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patnloop2"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patwait2"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + descrToFuncMap[i].m_pFuncName="patwaittime2"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPattern; + i++; + + + /* pulse */ + + descrToFuncMap[i].m_pFuncName="pulse"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPulse; + i++; + + descrToFuncMap[i].m_pFuncName="pulsenmove"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPulse; + i++; + + descrToFuncMap[i].m_pFuncName="pulsechip"; // + descrToFuncMap[i].m_pFuncPtr=&slsDetectorCommand::cmdPulse; + i++; + + + numberOfCommands=i; + + // #ifdef VERBOSE + // cout << "Number of commands is " << numberOfCommands << endl; + // #endif +} + + + + + + +string slsDetectorCommand::executeLine(int narg, char *args[], int action) { + + + + if (action==READOUT_ACTION) + return cmdAcquire(narg, args, action); + + + size_t s=string(args[0]).find(':'); + string key=string(args[0]).substr(0,s); // truncate at : + + if (action==PUT_ACTION && narg<1) + action=HELP_ACTION; + + + for(int i=0; isetOnline(ONLINE_FLAG); + + if(myDet->acquire() == FAIL) + return string("acquire unsuccessful"); + if(myDet->setReceiverOnline()==ONLINE_FLAG){ + char answer[100]; + sprintf(answer,"\n%d",myDet->getFramesCaughtByReceiver()); + return string(answer); + } + + return string(""); + +} + + + + +string slsDetectorCommand::helpAcquire(int narg, char *args[], int action){ + + + if (action==PUT_ACTION) + return string(""); + ostringstream os; + os << "Usage is "<< std::endl << "sls_detector_acquire id " << std::endl; + os << "where id is the id of the detector " << std::endl; + os << "the detector will be started, the data acquired, processed and written to file according to the preferences configured " << std::endl; + return os.str(); + +} + + +string slsDetectorCommand::cmdData(int narg, char *args[], int action) { + +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + int b; + if (action==PUT_ACTION) { + return string("cannot set"); + } else if (action==HELP_ACTION) { + return helpData(narg,args,HELP_ACTION); + } else { + b=myDet->setThreadedProcessing(-1); + myDet->setThreadedProcessing(0); + myDet->setOnline(ONLINE_FLAG); + myDet->readAll(); + //processdata in receiver is useful only for gui purposes + if(myDet->setReceiverOnline()==OFFLINE_FLAG) + myDet->processData(1); + myDet->setThreadedProcessing(b); + return string(""); + } +} + + + +string slsDetectorCommand::helpData(int narg, char *args[], int action){ + + if (action==PUT_ACTION) + return string(""); + else + return string("data \t gets all data from the detector (if any) processes them and writes them to file according to the preferences already setup\n"); + +} + +string slsDetectorCommand::cmdFrame(int narg, char *args[], int action) { + + int b; +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + if (action==PUT_ACTION) { + return string("cannot set"); + } else if (action==HELP_ACTION) { + return helpFrame(narg,args,HELP_ACTION); + } else { + b=myDet->setThreadedProcessing(-1); + myDet->setThreadedProcessing(0); + myDet->setOnline(ONLINE_FLAG); + myDet->readFrame(); + //processdata in receiver is useful only for gui purposes + if(myDet->setReceiverOnline()==OFFLINE_FLAG) + myDet->processData(1); + myDet->setThreadedProcessing(b); + return string("ok"); + } + +} + +string slsDetectorCommand::helpFrame(int narg, char *args[], int action) { + + if (action==PUT_ACTION) + return string(""); + return string("frame \t gets a single frame from the detector (if any) processes it and writes it to file according to the preferences already setup\n"); + +} + +string slsDetectorCommand::cmdStatus(int narg, char *args[], int action) { + +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) { + //myDet->setThreadedProcessing(0); + if (string(args[1])=="start") + myDet->startAcquisition(); + else if (string(args[1])=="stop") + myDet->stopAcquisition(); + else + return string("unknown action"); + } else if (action==HELP_ACTION) { + return helpStatus(narg,args,HELP_ACTION); + } + runStatus s=myDet->getRunStatus(); + return myDet->runStatusType(s); + +} + + + +string slsDetectorCommand::helpStatus(int narg, char *args[], int action) { + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("status \t gets the detector status - can be: running, error, transmitting, finished, waiting or idle\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("status \t controls the detector acquisition - can be start or stop \n"); + return os.str(); +} + + +string slsDetectorCommand::cmdFree(int narg, char *args[], int action) { + +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + if (action==HELP_ACTION) { + return helpFree(narg,args,HELP_ACTION); + } + myDet->freeSharedMemory(); + return("freed"); +} + + +string slsDetectorCommand::helpFree(int narg, char *args[], int action) { + + return string("free \t frees the shared memory\n"); + +} + + +string slsDetectorCommand::cmdAdd(int narg, char *args[], int action) { +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + int ivar, ival; + string var=string(args[0]); + ostringstream os; + if (action==HELP_ACTION) { + return helpAdd(narg,args,HELP_ACTION); + } else if (action==PUT_ACTION) { + size_t p=string(args[0]).find(':'); + if (p==string::npos) + ivar=-1; + else { + istringstream vvstr(var.substr(p+1)); + vvstr >> ivar; + if (vvstr.fail()) + ivar=-1; //append at the end + } + + if (sscanf(args[1],"%d",&ival)) { + // add by detector id + os<< myDet->addSlsDetector(ival, ivar)<< endl;; + } else { + //add by hostname + os<< myDet->addSlsDetector(args[1], ivar)<< endl; + } + return os.str(); + } + return string("cannot get"); + +} + + +string slsDetectorCommand::helpAdd(int narg, char *args[], int action){ + return string("add[:i] det \t adds a detector in position i to the multi detector structure. i is the detector position, default is appended. det can either be the detector hostname or the detector id. Returns -1 if it fails or the total number of detectors in the multidetector structure\n"); +} + +string slsDetectorCommand::cmdRemove(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + + + ostringstream os; + int ival;//ivar, + string var=string(args[0]); + + if (action==HELP_ACTION) { + return helpRemove(narg,args,HELP_ACTION); + } else if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) { + // remove detector in position ival + os << myDet->removeSlsDetector(ival); + } else { + // remove detector by hostname + os<< myDet->removeSlsDetector(args[1]); + } + return os.str(); + } + return string("cannot get"); + +} + +string slsDetectorCommand::helpRemove(int narg, char *args[], int action){ + return string("remove det \t removes a detector. det can either be the detector hostname or the detector position. Returns the total number of detectors in the multidetector structure\n"); +} + +string slsDetectorCommand::cmdHostname(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + + if (action==HELP_ACTION) { + return helpHostname(narg,args,HELP_ACTION); + } + + ostringstream os; + int ivar=-1;//, ival; + string var=string(args[0]); + char hostname[1000]; + + + size_t p=string(args[0]).find(':'); + if (p==string::npos) + ivar=-1; + else { + istringstream vvstr(var.substr(p+1)); + vvstr >> ivar; + if (vvstr.fail()) + ivar=-1; + } + + + + p=string(args[0]).find("hostname"); + + if (p==string::npos) { + //type + // cout << "should add by type!" << endl; + + if (action==PUT_ACTION) { + //add by type + if (ivar==-1) { + strcpy(hostname,""); + for (int id=1; id2) + strcat(hostname,"+"); + } + } else + strcpy(hostname,args[1]); + + myDet->ssetDetectorsType(hostname, ivar); + } + return myDet->sgetDetectorsType(ivar); + } else { + if (action==PUT_ACTION) { + //add by hostname + if (ivar==-1) { + strcpy(hostname,""); + for (int id=1; id2) + strcat(hostname,"+"); + } + } else + strcpy(hostname,args[1]); + myDet->setHostname(hostname, ivar); + } + + return string(myDet->getHostname(ivar)); + } + +} + + + +string slsDetectorCommand::helpHostname(int narg, char *args[], int action){ + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("hostname[:i] \t returns the hostname(s) of the detector structure. i is the detector position in a multi detector system\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("hostname[:i] name [name name]\t configures the hostnames of the detector structure. i is the detector position in a multi detector system\n"); + return os.str(); +} + + +string slsDetectorCommand::cmdId(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + + + if (action==HELP_ACTION) { + return helpId(narg,args,HELP_ACTION); + } + + ostringstream os; + int ivar, ival; + string var=string(args[0]); + // char answer[1000]; + + + size_t p=string(args[0]).find(':'); + if (p==string::npos) + ivar=-1; + else { + istringstream vvstr(var.substr(p+1)); + vvstr >> ivar; + if (vvstr.fail()) + ivar=-1; + } + + if (action==PUT_ACTION) { + //add by hostname + istringstream vvstr(args[1]); + + vvstr >> ival; + if (vvstr.fail()) + ival=-1; + + myDet->setDetectorId(ival, ivar); + } + os << myDet->getDetectorId(ivar); + + return os.str(); + +} + +string slsDetectorCommand::helpId(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("id[:i] \t returns the id of the detector structure. i is the detector position in a multi detector system\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("id:i l]\t configures the id of the detector structure. i is the detector position in a multi detector system and l is the id of the detector to be added\n"); + + return os.str(); +} + +string slsDetectorCommand::cmdMaster(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); + +#endif + + ostringstream os; + int ival; + + + if (action==HELP_ACTION) { + return helpMaster(narg,args,HELP_ACTION); + } + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) { + istringstream vvstr(args[1]); + vvstr >> ival; + if (vvstr.fail()) + return helpMaster(narg,args,HELP_ACTION); + myDet->setMaster(ival); + } + os << myDet->setMaster(); + return os.str(); + +} + + +string slsDetectorCommand::helpMaster(int narg, char *args[], int action){ + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("master \t gets the master of the detector structure (-1 if none)\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("master pos \t sets position of the master of the detector structure (-1 if none) \n"); + return os.str(); + +} + +string slsDetectorCommand::cmdSync(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + + if (action==HELP_ACTION) { + return helpSync(narg,args,HELP_ACTION); + } + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) { + if (myDet->getSyncType(string(args[1]))==GET_SYNCHRONIZATION_MODE) return helpSync(narg,args, action); + myDet->setSynchronization(myDet->getSyncType(string(args[1]))); + } + return myDet->getSyncType(myDet->setSynchronization()); + +} +string slsDetectorCommand::helpSync(int narg, char *args[], int action){ + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("sync \t gets the synchronization mode of the structure\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("sync mode \t sets synchronization mode of the structure. Cane be none, gating, trigger, complementary \n"); + return os.str(); +} + +string slsDetectorCommand::cmdHelp(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + + cout << narg << endl; + + if (narg>=1) + return helpLine(narg-1, args+1, action); + else + return helpLine(0, args, action); + + + +} + +string slsDetectorCommand::cmdExitServer(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + if (action==HELP_ACTION) { + return helpExitServer(narg, args, action); + } + + if (action==PUT_ACTION) { + if (cmd=="exitserver"){ + myDet->setOnline(ONLINE_FLAG); + if (myDet->exitServer()!=OK) + return string("Server shut down."); + else + return string("Error closing server\n"); + } + else if (cmd=="exitreceiver"){ + if(myDet->exitReceiver()!=OK) + return string("Receiver shut down\n"); + else + return string("Error closing receiver\n"); + } + else return("cannot decode command\n"); + } else + return ("cannot get"); + +} + +string slsDetectorCommand::helpExitServer(int narg, char *args[], int action){ + ostringstream os; + os << string("exitserver \t shuts down all the detector servers. Don't use it!!!!\n"); + os << string("exitreceiver \t shuts down all the receiver servers.\n"); + return os.str(); +} + + +string slsDetectorCommand::cmdSettingsDir(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + if (action==HELP_ACTION) { + return helpSettingsDir(narg, args, action); + } + if (action==PUT_ACTION) { + myDet->setSettingsDir(string(args[1])); + } + if (myDet->getSettingsDir()==NULL) + return string("undefined"); + return string(myDet->getSettingsDir()); +} + + + +string slsDetectorCommand::helpSettingsDir(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("settingsdir \t gets the directory where the settings files are located\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("settingsdir dir \t sets the directory where the settings files are located\n"); + if (action==GET_ACTION || action==HELP_ACTION) + os << string("trimdir \t obsolete for settingsdir\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("trimdir dir \t obsolete for settingsdir\n"); + return os.str(); +} + + + +string slsDetectorCommand::cmdCalDir(int narg, char *args[], int action){ + + if (action==HELP_ACTION) { + return helpCalDir(narg, args, action); + } + if (action==PUT_ACTION) { + myDet->setCalDir(string(args[1])); + } + if (myDet->getCalDir()==NULL) + return string("undefined"); + return string(myDet->getCalDir()); +} + + + +string slsDetectorCommand::helpCalDir(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("caldir \t gets the directory where the calibration files are located\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("caldir dir \t sets the directory where the calibration files are located\n"); + return os.str(); +} + + + +string slsDetectorCommand::cmdTrimEn(int narg, char *args[], int action){ + int ival; + int ip; + + char answer[1000]; + + if (action==HELP_ACTION) return helpTrimEn(narg,args,action); + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) { + int pos[ival]; + for (ip=0; ipsetTrimEn(ip,pos); + } + } + int npos=myDet->getTrimEn(); + sprintf(answer,"%d",npos); + int opos[npos]; + myDet->getTrimEn(opos); + for (int ip=0; ipsetFilePath(string(args[1])); + + return string(myDet->getFilePath()); +} + + + +string slsDetectorCommand::helpOutDir(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("outdir \t gets the directory where the output files will be written\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("outdir dir \t sets the directory where the output files will be written\n"); + return os.str(); +} + + + + +string slsDetectorCommand::cmdFileName(int narg, char *args[], int action){ + if (action==HELP_ACTION) + return helpFileName(narg, args, action); + if (cmd=="fname") { + if (action==PUT_ACTION) + myDet->setFileName(string(args[1])); + + return string(myDet->getFileName()); + } else + return string(myDet->getCurrentFileName()); + +} + + + +string slsDetectorCommand::helpFileName(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("fname \t gets the filename for the data without index and extension\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("fname s \t sets the filename for the data (index and extension will be automatically appended)\n"); + return os.str(); +} + + + +string slsDetectorCommand::cmdEnablefwrite(int narg, char *args[], int action){ + + int i; + char ans[100]; + + if (action==HELP_ACTION) { + return helpEnablefwrite(narg, args, action); + } + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&i)) + myDet->enableWriteToFile(i); + else + return string("could not decode enable file write"); + + + } + sprintf(ans,"%d",myDet->enableWriteToFile()); + return string(ans); +} + + + +string slsDetectorCommand::helpEnablefwrite(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("When Enabled writes the data into the file\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string(" i \t should be 1 or 0 or -1\n"); + return os.str(); +} + + +string slsDetectorCommand::cmdOverwrite(int narg, char *args[], int action){ + + int i; + char ans[100]; + + if (action==HELP_ACTION) { + return helpOverwrite(narg, args, action); + } + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&i)) + myDet->overwriteFile(i); + else + return string("could not decode overwrite"); + + + } + sprintf(ans,"%d",myDet->overwriteFile()); + return string(ans); +} + + + +string slsDetectorCommand::helpOverwrite(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("When Enabled overwrites files\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string(" i \t should be 1 or 0 or -1\n"); + return os.str(); +} + + + +string slsDetectorCommand::cmdFileIndex(int narg, char *args[], int action){ + char ans[100]; + int i; + + if (action==HELP_ACTION) { + return helpFileName(narg, args, action); + } + else if (action==PUT_ACTION){ + if(!sscanf(args[1],"%d",&i)) + return string("cannot parse file index"); + myDet->setFileIndex(i); + } + + sprintf(ans,"%d", myDet->getFileIndex()); + return string(ans); +} + + + +string slsDetectorCommand::helpFileIndex(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("index \t gets the file index for the next the data file\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("fname i \t sets the fileindex for the next data file\n"); + return os.str(); +} + + +string slsDetectorCommand::cmdFlatField(int narg, char *args[], int action){ + + if (action==HELP_ACTION) { + return helpFlatField(narg, args, action); + } + string sval; + + if (string(args[0])==string("ffdir")) { + if (action==PUT_ACTION) { + sval=string(args[1]); + if (sval=="none") + sval=""; + myDet->setFlatFieldCorrectionDir(sval); + } + return string(myDet->getFlatFieldCorrectionDir()); + + } else if (string(args[0])==string("flatfield")) { + + if (action==PUT_ACTION) { + sval=string(args[1]); + if (sval=="none") + sval=""; + myDet->setFlatFieldCorrection(sval); + return string(myDet->getFlatFieldCorrectionFile()); + + } else {// if (action==GET_ACTION) { + if (narg>1) + sval=string(args[1]); + else + sval="none"; + // cout << myDet->getMaxNumberOfChannels() << endl; + double corr[ myDet->getMaxNumberOfChannels()], ecorr[myDet->getMaxNumberOfChannels()]; + if (myDet->getFlatFieldCorrection(corr,ecorr)) { + if (sval!="none") { + myDet->writeDataFile(sval,corr,ecorr,NULL,'i'); + return sval; + } + return string(myDet->getFlatFieldCorrectionFile()); + } else { + return string("none"); + } + } + } + return string("could not decode flat field action ")+cmd; + +} + + +string slsDetectorCommand::helpFlatField(int narg, char *args[], int action){ + + int t=0; + ostringstream os; + if (string(args[0])==string("ffdir")) { + t=1; + } else if (string(args[0])==string("flatfield")) { + t=2; + } + if (t!=1) { + + if (action==GET_ACTION || action==HELP_ACTION) { + os << string("flatfield [fn]\t gets the flat field file name. the coorection values and errors can be dumped to fn if specified. \n"); + } if (action==PUT_ACTION || action==HELP_ACTION) + os << string("flatfield s \t sets the flat field file name\n"); + } + if (t!=2) { + + if (action==GET_ACTION || action==HELP_ACTION) + os << string("ffdir \t gets the path for the flat field files \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("ffdir s \t sets the path for flat field files\n"); + } + return os.str(); + +} + + + + + +string slsDetectorCommand::cmdRateCorr(int narg, char *args[], int action){ + + if (action==HELP_ACTION) { + return helpRateCorr(narg, args, action); + } + double fval; + char answer[1000]; + + if (action==PUT_ACTION) { + sscanf(args[1],"%lf",&fval); + myDet->setRateCorrection(fval); + } + double t; + if (myDet->getRateCorrection(t)) { + sprintf(answer,"%0.9f",t); + } else { + sprintf(answer,"%f",0.); + } + return string(answer); +} + + +string slsDetectorCommand::helpRateCorr(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("ratecorr \t returns the dead time used for rate correections in ns \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("ratecorr ns \t sets the deadtime correction constant in ns, -1 in Eiger will set it to default tau of settings\n"); + return os.str(); + +} + + + + +string slsDetectorCommand::cmdBadChannels(int narg, char *args[], int action){ + + string sval; + + if (action==HELP_ACTION) { + return helpBadChannels(narg, args, action); + } + if (action==PUT_ACTION) { + sval=string(args[1]); + if (sval=="none") + sval=""; + myDet->setBadChannelCorrection(sval); + } else if (action==GET_ACTION) { + if (narg>1) + sval=string(args[1]); + else + sval="none"; + int bch[myDet->getMaxNumberOfChannels()], nbch; + if ((nbch=myDet->getBadChannelCorrection(bch))) { + if (sval!="none") { + ofstream outfile; + outfile.open (sval.c_str(),ios_base::out); + if (outfile.is_open()) { + for (int ich=0; ichgetBadChannelCorrectionFile()); + +} + + +string slsDetectorCommand::helpBadChannels(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("badchannels [fn]\t returns the badchannels file. Prints the list of bad channels in fn, if specified. \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("badchannels \t sets the bad channels list\n"); + + return os.str(); +} + + + +string slsDetectorCommand::cmdAngConv(int narg, char *args[], int action){ + + if (action==HELP_ACTION) { + return helpAngConv(narg, args, action); + } + string sval; + char answer[1000]; + double fval; + angleConversionParameter c; + + if (string(args[0])==string("angconv")) { + if (action==PUT_ACTION) { + sval=string(args[1]); + + if (sval=="none") + sval=""; + + myDet->setAngularConversionFile(sval); + + return string(myDet->getAngularConversionFile()); + } else if (action==GET_ACTION) { + if (narg>1) + sval=string(args[1]); + else + sval="none"; + int dir; + if (myDet->getAngularConversion(dir)) { + if (sval!="none") { + myDet->writeAngularConversion(sval.c_str()); + return sval; + } + return string(myDet->getAngularConversionFile()); + } else { + return string("none"); + } + } + } else if (string(args[0])==string("globaloff")) { + c=GLOBAL_OFFSET; + + + } else if (string(args[0])==string("fineoff")) { + c=FINE_OFFSET; + + + } else if (string(args[0])==string("binsize")) { + c=BIN_SIZE; + + } else if (string(args[0])==string("angdir")) { + c=ANGULAR_DIRECTION; + + } else if (string(args[0])==string("moveflag")) { + c=MOVE_FLAG; + } else if (string(args[0])==string("samplex")) { + c=SAMPLE_X; + } else if (string(args[0])==string("sampley")) { + c=SAMPLE_Y; + } + + + else + return string("could not decode angular conversion parameter ")+cmd; + + + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%lf",&fval)) + myDet->setAngularConversionParameter(c,fval); + } + sprintf(answer,"%f",myDet->getAngularConversionParameter(c)); + return string(answer); + + +} + + +string slsDetectorCommand::helpAngConv(int narg, char *args[], int action){ + + + int t=0xffff; + ostringstream os; + + if (string(args[0])==string("angconv")) { + t=1; + } else if (string(args[0])==string("globaloff")) { + t=2; + } else if (string(args[0])==string("fineoff")) { + t=4; + } else if (string(args[0])==string("binsize")) { + t=8; + } else if (string(args[0])==string("samplex")) { + t=16; + } else if (string(args[0])==string("sampley")) { + t=32; + } + if (t&1) { + if (action==GET_ACTION || action==HELP_ACTION) + os << string("angconv [fn]\t returns the constants used for angular conversion prints them to the file fn if specified \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("angconv fn\t sets the angualr conversion constants (none unsets) \n"); + } if (t&2) { + if (action==GET_ACTION || action==HELP_ACTION) + os << string("globaloff\t returns the global offset used for angular conversion \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("globaloff f\t sets the global offset used for the angular conversion \n"); + + + } if (t&4) { + if (action==GET_ACTION || action==HELP_ACTION) + os << string("fineoff\t returns the fine offset used for angular conversion \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("fineoff f\t sets the fine offset used for the angular conversion \n"); + + + + } if (t&8) { + if (action==GET_ACTION || action==HELP_ACTION) + os << string("binsize\t returns the bin size used for the angular conversion \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("binsize f\t sets the bin size used for the angular conversion \n"); + + } + if (t&16) { + if (action==GET_ACTION || action==HELP_ACTION) + os << string("samplex \t gets the sample displacement in th direction parallel to the beam \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("samplex f\t sets the sample displacement in th direction parallel to the beam \n"); + } + if (t&32) { + if (action==GET_ACTION || action==HELP_ACTION) + os << string("sampley \t gets the sample displacement in the direction orthogonal to the beam \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("sampley f\t sets the sample displacement in the direction orthogonal to the beam \n"); + } + + return os.str(); +} + + +string slsDetectorCommand::cmdThreaded(int narg, char *args[], int action){ + int ival; + char answer[1000]; + + if (action==HELP_ACTION) + return helpThreaded(narg,args,action); + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) + myDet->setThreadedProcessing(ival); + } + sprintf(answer,"%d",myDet->setThreadedProcessing()); + return string(answer); + +} + + +string slsDetectorCommand::helpThreaded(int narg, char *args[], int action){ + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("threaded \t returns wether the data processing is threaded. \n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("threaded t \t sets the threading flag ( 1sets, 0 unsets).\n"); + + return os.str(); + +} + + +string slsDetectorCommand::cmdImage(int narg, char *args[], int action){ + string sval; + int retval; + if (action==HELP_ACTION) + return helpImage(narg,args,HELP_ACTION); + else if (action==GET_ACTION) + return string("Cannot get"); + + sval=string(args[1]); + myDet->setOnline(ONLINE_FLAG); + + + if (string(args[0])==string("darkimage")) + retval=myDet->loadImageToDetector(DARK_IMAGE,sval); + else if (string(args[0])==string("gainimage")) + retval=myDet->loadImageToDetector(GAIN_IMAGE,sval); + + + if(retval==OK) + return string("Image loaded succesfully"); + else + return string("Image load failed"); +} + + +string slsDetectorCommand::helpImage(int narg, char *args[], int action){ + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION){ + os << "darkimage f \t loads the image to detector from file f"<< std::endl; + os << "gainimage f \t loads the image to detector from file f"<< std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION){ + os << "darkimage \t Cannot get"<< std::endl; + os << "gainimage \t Cannot get"<< std::endl; + } + return os.str(); +} + + +string slsDetectorCommand::cmdCounter(int narg, char *args[], int action){ + int ival; + char answer[100]; + string sval; + int retval; + if (action==HELP_ACTION) + return helpCounter(narg,args,HELP_ACTION); + else if (action==PUT_ACTION) + ival=atoi(args[1]); + + myDet->setOnline(ONLINE_FLAG); + + if (string(args[0])==string("readctr")){ + if (action==PUT_ACTION) + return string("Cannot put"); + else{ + if (narg<3) + return string("should specify I/O file"); + sval=string(args[2]); + retval=myDet->writeCounterBlockFile(sval,ival); + } + } + else if (string(args[0])==string("resetctr")){ + if (action==GET_ACTION) + return string("Cannot get"); + else + retval=myDet->resetCounterBlock(ival); + } + + else if (string(args[0])==string("resmat")){ + if (action==PUT_ACTION){ + if (!sscanf(args[1],"%d",&ival)) + return string("Could not scan resmat input ")+string(args[1]); + if(ival>=0) + sprintf(answer,"%d",myDet->setCounterBit(ival)); + }else + sprintf(answer,"%d",myDet->setCounterBit()); + return string(answer); + } + + if(retval==OK) + return string("Counter read/reset succesfully"); + else + return string("Counter read/reset failed"); +} + + +string slsDetectorCommand::helpCounter(int narg, char *args[], int action){ + ostringstream os; + os << std::endl; + if (action==PUT_ACTION || action==HELP_ACTION){ + os << "readctr \t Cannot put"<< std::endl; + os << "resetctr i \t resets counter in detector, restarts acquisition if i=1"<< std::endl; + os << "resmat i \t sets/resets counter bit in detector"<< std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION){ + os << "readctr i fname\t reads counter in detector to file fname, restarts acquisition if i=1"<< std::endl; + os << "resetctr \t Cannot get"<< std::endl; + os << "resmat i \t gets the counter bit in detector"<< std::endl; + } + return os.str(); +} + + + + +string slsDetectorCommand::cmdPositions(int narg, char *args[], int action){ + int ival; + int ip; + + char answer[1000]; + + if (action==HELP_ACTION) return helpPositions(narg,args,action); + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) { + double pos[ival]; + for (ip=0; ipsetPositions(ip,pos); + } + } + int npos=myDet->getPositions(); + sprintf(answer,"%d",npos); + double opos[npos]; + myDet->getPositions(opos); + for (int ip=0; ipsetActionParameter(ia, args[1]); + } + return string(myDet->getActionParameter(ia)); + + } else { + + if (ia==enCalLog || ia==angCalLog) { + + + if (action==PUT_ACTION) { + + int arg=-1; + + + sscanf(args[1],"%d",&arg); + + if (arg==0) + myDet->setActionScript(ia,"none"); + else + myDet->setActionScript(ia,args[1]); + + } + + sprintf(answer,"%d",myDet->getActionMode(ia)); + return string(answer); + + } + + + if (action==PUT_ACTION) { + myDet->setActionScript(ia, args[1]); + } + return string(myDet->getActionScript(ia)); + + } + return string("could not decode command")+cmd; + + + + +} + +string slsDetectorCommand::helpScripts(int narg, char *args[], int action) { + + ostringstream os; + + if (narg>0) { + if ((string(args[0]).find("start")!=string::npos) || (string(args[0]).find("stop")!=string::npos) || (string(args[0]).find("scriptbefore")!=string::npos) || \ + (string(args[0]).find("scriptafter")!=string::npos) || (string(args[0]).find("headerafter")!=string::npos) || (string(args[0]).find("headerbefore")!=string::npos)) { + + + if (action==PUT_ACTION || action==HELP_ACTION) + os << args[0] << " script \t sets the script to execute for the corresponding action"<< std::endl; + if (action==GET_ACTION || action==HELP_ACTION) + os << args[0] << " \t returns the script to execute for the corresponding action"<< std::endl; + + } + + + if ((string(args[0]).find("encallog")!=string::npos) || (string(args[0]).find("angcallog")!=string::npos)) { + + + + if (action==PUT_ACTION || action==HELP_ACTION) + os << args[0] << " i \t enables (1) or disables (0) the logging for the calibration"<< std::endl; + if (action==GET_ACTION || action==HELP_ACTION) + os << args[0] << " \t returns the calibration log mode"<< std::endl; + } + } + return os.str(); + +} + +string slsDetectorCommand::cmdScans(int narg, char *args[], int action) { + + int is=-1, ival, ns=0; + char answer[MAX_SCAN_STEPS*10]; + double *values; + if (action==HELP_ACTION) + return helpScans(narg,args,action); + + + if (cmd.find("0")!=string::npos) is=0; + else if (cmd.find("1")!=string::npos) is=1; + else return string("cannot define scan level ")+cmd; + + if (cmd.find("par")!=string::npos) { + if (action==PUT_ACTION) { + myDet->setScanParameter(is, args[1]); + } + return myDet->getScanParameter(is); + } + if (cmd.find("script")!=string::npos) { + if (action==PUT_ACTION) { + myDet->setScanScript(is, args[1]); + } + return myDet->getScanScript(is); + } + if (cmd.find("prec")!=string::npos) { + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) { + myDet->setScanPrecision(is, ival); + } else + return string("invalid precision ")+cmd; + } + sprintf(answer,"%d", myDet->getScanPrecision(is)); + return string(answer); + } + if (cmd.find("steps")!=string::npos) { + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) { + + if (ival>MAX_SCAN_STEPS) + return string("too many steps required!"); + + values=new double[ival]; + for (int i=0; i=(i+2)) { + if (sscanf(args[i+2],"%lf",values+i)) + ns++; + else + break; + } else + break; + } + myDet->setScanSteps(is, ns, values); + delete [] values; + } else { + return string("invalid number of steps ")+string(args[1]); + } + } + ns=myDet->getScanSteps(is); + sprintf(answer,"%d ",ns); + if (ns>0) { + values=new double[ns]; + ns=myDet->getScanSteps(is, values); + int p=myDet->getScanPrecision(is); + char format[1000]; + sprintf(format, "%%s %%0.%df",p); + for (int i=0; iMAX_SCAN_STEPS) + return string("too many steps required!"); + + if (fmax>fmin) + if (fstep<0) + fstep=-1*fstep; + + if (fmax0) + fstep=-1*fstep; + + + values=new double[ns]; + for (int i=0; isetScanSteps(is, ns, values); + delete [] values; + } + + ns=myDet->getScanSteps(is); + values=new double[ns]; + ns=myDet->getScanSteps(is, values); + int p=myDet->getScanPrecision(is); + char format[1000]; + sprintf(format, "%%s %%0.%df",p); + sprintf(answer,"%d ",ns); + for (int i=0; isetOnline(ONLINE_FLAG); + + if (cmd=="detectormac") { + t=DETECTOR_MAC; + } else if (cmd=="detectorip") { + t=DETECTOR_IP; + } else if (cmd=="rx_hostname") { + t=RECEIVER_HOSTNAME; + } else if (cmd=="rx_udpip") { + t=RECEIVER_UDP_IP; + } else if (cmd=="rx_udpmac") { + t=RECEIVER_UDP_MAC; + } else if (cmd=="rx_udpport") { + t=RECEIVER_UDP_PORT; + if (action==PUT_ACTION){ + if (!(sscanf(args[1],"%d",&i))) + return ("cannot parse argument") + string(args[1]); + } + } else if (cmd=="rx_udpport2") { + t=RECEIVER_UDP_PORT2; + if (action==PUT_ACTION){ + if (!(sscanf(args[1],"%d",&i))) + return ("cannot parse argument") + string(args[1]); + } + } else if (cmd=="txndelay_left") { + t=DETECTOR_TXN_DELAY_LEFT; + if (action==PUT_ACTION){ + if (!(sscanf(args[1],"%d",&i))) + return ("cannot parse argument") + string(args[1]); + } + } else if (cmd=="txndelay_right") { + t=DETECTOR_TXN_DELAY_RIGHT; + if (action==PUT_ACTION){ + if (!(sscanf(args[1],"%d",&i))) + return ("cannot parse argument") + string(args[1]); + } + } else if (cmd=="txndelay_frame") { + t=DETECTOR_TXN_DELAY_FRAME; + if (action==PUT_ACTION){ + if (!(sscanf(args[1],"%d",&i))) + return ("cannot parse argument") + string(args[1]); + } + } else if (cmd=="flowcontrol_10g") { + t=FLOW_CONTROL_10G; + if (action==PUT_ACTION){ + if (!(sscanf(args[1],"%d",&i))) + return ("cannot parse argument") + string(args[1]); + } + }else return ("unknown network parameter")+cmd; + + if (action==PUT_ACTION) + myDet->setNetworkParameter(t, args[1]); + + return myDet->getNetworkParameter(t); + +} + +string slsDetectorCommand::helpNetworkParameter(int narg, char *args[], int action) { + + + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "detectormac mac \n sets detector mac to mac"<< std::endl; + os << "detectorip ip \n sets detector ip to ip"<< std::endl; + os << "rx_hostname name \n sets receiver ip/hostname to name"<< std::endl; + os << "rx_udpip ip \n sets receiver udp ip to ip"<< std::endl; + os << "rx_udpmac mac \n sets receiver udp mac to mac"<< std::endl; + os << "rx_udpport port \n sets receiver udp port to port"<< std::endl; + os << "rx_udpport2 port \n sets receiver udp port to port. For Eiger, it is the second half module and for other detectors, same as rx_udpport"<< std::endl; + os << "txndelay_left port \n sets detector transmission delay of the left port"<< std::endl; + os << "txndelay_right port \n sets detector transmission delay of the right port"<< std::endl; + os << "txndelay_frame port \n sets detector transmission delay of the entire frame"<< std::endl; + os << "flowcontrol_10g port \n sets flow control for 10g for eiger"<< std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "detectormac \n gets detector mac "<< std::endl; + os << "detectorip \n gets detector ip "<< std::endl; + os << "rx_hostname \n gets receiver ip "<< std::endl; + os << "rx_udpmac \n gets receiver udp mac "<< std::endl; + os << "rx_udpport \n gets receiver udp port "<< std::endl; + os << "rx_udpport2 \n gets receiver udp port. For Eiger, it is the second half module and for other detectors, same as rx_udpport"<< std::endl; + os << "txndelay_left \n gets detector transmission delay of the left port"<< std::endl; + os << "txndelay_right \n gets detector transmission delay of the right port"<< std::endl; + os << "txndelay_frame \n gets detector transmission delay of the entire frame"<< std::endl; + os << "flowcontrol_10g \n sets flow control for 10g for eiger"<< std::endl; + } + return os.str(); + + +} + +string slsDetectorCommand::cmdPort(int narg, char *args[], int action) { + + if (action==HELP_ACTION) + return helpPort(narg,args,action); + int val; //ret, + char ans[1000]; + portType index; + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&val)) + ; + else + return string("could not scan port number")+string(args[1]); + } + + if (cmd=="port") { + index=CONTROL_PORT; + } else if (cmd=="rx_tcpport") { + index=DATA_PORT; + } else if (cmd=="stopport") { + index=STOP_PORT; + } else + return string("unknown port type ")+cmd; + + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) + myDet->setPort(index,val); + + sprintf(ans,"%d",myDet->setPort(index)); + return string(ans); + +} + + + +string slsDetectorCommand::helpPort(int narg, char *args[], int action) { + + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "port i \n sets the communication control port"<< std::endl; + os << "rx_tcpport i \n sets the communication receiver port"<< std::endl; + os << "stopport i \n sets the communication stop port "<< std::endl; + + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "port \n gets the communication control port"<< std::endl; + os << "rx_tcpport \n gets the communication receiver port"<< std::endl; + os << "stopport \n gets the communication stop port "<< std::endl; + } + return os.str(); + + +} + + +string slsDetectorCommand::cmdLock(int narg, char *args[], int action) { + + if (action==HELP_ACTION) + return helpLock(narg,args,action); + + int val;//, ret; + char ans[1000]; + + if(cmd=="lock"){ + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&val)) + myDet->lockServer(val); + else + return string("could not lock status")+string(args[1]); + } + + sprintf(ans,"%d",myDet->lockServer()); + } + + + else if(cmd=="r_lock"){ + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&val)) + myDet->lockReceiver(val); + else + return string("could not decode lock status")+string(args[1]); + } + sprintf(ans,"%d",myDet->lockReceiver()); + } + + + else + return string("could not decode command"); + + return string(ans); +} + + + +string slsDetectorCommand::helpLock(int narg, char *args[], int action) { + + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "lock i \n locks (1) or unlocks (0) the detector to communicate to this client"<< std::endl; + os << "r_lock i \n locks (1) or unlocks (0) the receiver to communicate to this client"<< std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "lock \n returns the detector lock status"<< std::endl; + os << "r_lock \n returns the receiver lock status"<< std::endl; + } + return os.str(); + + +} + + +string slsDetectorCommand::cmdLastClient(int narg, char *args[], int action) { + + if (action==HELP_ACTION) + return helpLastClient(narg,args,action); + + if (action==PUT_ACTION) + return string("cannot set"); + + + if(cmd=="lastclient"){ + myDet->setOnline(ONLINE_FLAG); + return myDet->getLastClientIP(); + } + + else if(cmd=="r_lastclient") + return myDet->getReceiverLastClientIP(); + + return string("cannot decode command"); +} + +string slsDetectorCommand::helpLastClient(int narg, char *args[], int action) { + + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) { + os << "lastclient \n returns the last client communicating with the detector"<< std::endl; + os << "r_lastclient \n returns the last client communicating with the receiver"<< std::endl; + } + return os.str(); + +} + + +string slsDetectorCommand::cmdOnline(int narg, char *args[], int action) { + + if (action==HELP_ACTION) { + return helpOnline(narg,args,action); + } + int ival; + char ans[1000]; + + if(cmd=="online"){ + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) + myDet->setOnline(ival); + else + return string("Could not scan online mode ")+string(args[1]); + } + sprintf(ans,"%d",myDet->setOnline()); + } + else if(cmd=="checkonline"){ + if (action==PUT_ACTION) + return string("cannot set"); + strcpy(ans,myDet->checkOnline().c_str()); + if(!strlen(ans)) + strcpy(ans,"All online"); + else + strcat(ans," :Not online"); + } + else if(cmd=="activate"){ + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) { + if (!sscanf(args[1],"%d",&ival)) + return string("Could not scan activate mode ")+string(args[1]); + /* if(dynamic_cast(myDet) != NULL) + return string("Can only set it from the multiDetector mode");*/ + myDet->activate(ival); + } + sprintf(ans,"%d",myDet->activate()); + } + else if(cmd=="r_online"){ + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&ival)) + myDet->setReceiverOnline(ival); + else + return string("Could not scan online mode ")+string(args[1]); + } + sprintf(ans,"%d",myDet->setReceiverOnline()); + } + else{ + if (action==PUT_ACTION) + return string("cannot set"); + strcpy(ans,myDet->checkReceiverOnline().c_str()); + if(!strlen(ans)) + strcpy(ans,"All receiver online"); + else + strcat(ans," :Not receiver online"); + } + + return ans; +} + +string slsDetectorCommand::helpOnline(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "online i \n sets the detector in online (1) or offline (0) mode"<< std::endl; + os << "r_online i \n sets the receiver in online (1) or offline (0) mode"<< std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "online \n gets the detector online (1) or offline (0) mode"<< std::endl; + os << "checkonline \n returns the hostnames of all detectors in offline mode"<< std::endl; + os << "r_online \n gets the receiver online (1) or offline (0) mode"<< std::endl; + os << "r_checkonline \n returns the hostnames of all receiver in offline mode"<< std::endl; + } + return os.str(); + + +} + + + + +string slsDetectorCommand::cmdConfigureMac(int narg, char *args[], int action) { + + if (action==HELP_ACTION) { + return helpConfigureMac(narg,args,action); + } + int ret; + char ans[1000]; + + if (action==PUT_ACTION){ + myDet->setOnline(ONLINE_FLAG); + ret=myDet->configureMAC(); + } + else + return string("Cannot get ")+cmd; + + sprintf(ans,"%d",ret); + return ans; +} + +string slsDetectorCommand::helpConfigureMac(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) + os << "configuremac i \n configures the MAC of the detector."<< std::endl; + if (action==GET_ACTION || action==HELP_ACTION) + os << "configuremac " << "Cannot get " << std::endl; + + return os.str(); +} + + +string slsDetectorCommand::cmdDetectorSize(int narg, char *args[], int action) { + + if (action==HELP_ACTION) + return helpDetectorSize(narg,args,action); + int ret, val=-1, pos=-1,i; + char ans[1000], temp[100]; + + myDet->setOnline(ONLINE_FLAG); + + if (action==PUT_ACTION) { + if (cmd=="maxmod") + return string("cannot put!"); + else if (cmd=="roimask"){ + if (!sscanf(args[1],"%d",&val)) + return string("could not scan ")+string(args[0])+string(" ")+string(args[1]); + } + else if (!sscanf(args[1],"%d",&val)) + return string("could not scan ")+string(args[0])+string(" ")+string(args[1]); + + if (cmd=="roi"){ + //debug number of arguments + if ((val<0) || (narg!=((val*4)+2)) ) + return helpDetectorSize(narg,args,action); + ROI allroi[val]; + pos=2; + for(i=0;isetROI(val,allroi); + } + + if(cmd=="detsizechan"){ + if ((sscanf(args[1],"%d",&val)) && (val>0)) + myDet->setMaxNumberOfChannelsPerDetector(X,val); + if ((narg > 2) && (sscanf(args[2],"%d",&val)) && (val>0)) + myDet->setMaxNumberOfChannelsPerDetector(Y,val); + } + + } + + if (cmd=="nmod" || cmd=="roimask") { + ret=myDet->setNumberOfModules(val); + } else if (cmd=="maxmod") { + ret=myDet->getMaxNumberOfModules(); + } else if (cmd=="dr") { + ret=myDet->setDynamicRange(val); + } else if (cmd=="roi") { + myDet->getROI(ret); + } else if (cmd=="detsizechan") { + sprintf(ans,"%d",myDet->getMaxNumberOfChannelsPerDetector(X)); + sprintf(temp,"%d",myDet->getMaxNumberOfChannelsPerDetector(Y)); + strcat(ans," "); + strcat(ans,temp); + return string(ans); + } + else + return string("unknown detector size ")+cmd; + + if (cmd=="roimask") + sprintf(ans,"%x",ret); + else + sprintf(ans,"%d",ret); + + return string(ans); + +} + + +string slsDetectorCommand::helpDetectorSize(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "nmod i \n sets the number of modules of the detector"<< std::endl; + os << "dr i \n sets the dynamic range of the detector"<< std::endl; + os << "roi i xmin xmax ymin ymax \n sets region of interest where i is number of rois;i=0 to clear rois"<< std::endl; + os << "detsizechan x y \n sets the maximum number of channels for complete detector set in both directions; -1 is no limit"<< std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "nmod \n gets the number of modules of the detector"<< std::endl; + os << "maxmod \n gets the maximum number of modules of the detector"<< std::endl; + os << "dr \n gets the dynamic range of the detector"<< std::endl; + os << "roi \n gets region of interest"<< std::endl; + os << "detsizechan \n gets the maximum number of channels for complete detector set in both directions; -1 is no limit"<< std::endl; + + } + return os.str(); + + +} + + + +string slsDetectorCommand::cmdSettings(int narg, char *args[], int action) { + + if (action==HELP_ACTION) + return helpSettings(narg,args,action); + int val=-1;//ret, + char ans[1000]; + + + // portType index; + // if (sscanf(args[1],"%d",&val)) + // ; + // else + // return string("could not scan port number")+string(args[1]); + // } + + myDet->setOnline(ONLINE_FLAG); + + if (cmd=="settings") { + if (action==PUT_ACTION) + myDet->setSettings(myDet->getDetectorSettings(string(args[1]))); + return myDet->getDetectorSettings(myDet->getSettings()); + } else if (cmd=="threshold") { + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d",&val)) + myDet->setThresholdEnergy(val); + else + return string("invalid threshold value ")+cmd; + } + sprintf(ans,"%d",myDet->getThresholdEnergy()); + return string(ans); + } else if (cmd=="trimbits") { + if (narg>=2) { + string sval=string(args[1]); +#ifdef VERBOSE + std::cout<< " trimfile " << sval << std::endl; +#endif + if (action==GET_ACTION) { + //create file names + myDet->saveSettingsFile(sval, -1); + } else if (action==PUT_ACTION) { + myDet->loadSettingsFile(sval,-1); + } + } + return string(myDet->getSettingsFile()); + } else if (cmd=="trim") { + if (action==GET_ACTION) + return string("cannot get!"); + + trimMode mode=NOISE_TRIMMING; + int par1=0, par2=0; + if (string(args[0]).find("trim:")==string::npos) + return helpSettings(narg,args,action); + else if (string(args[0]).find("noise")!=string::npos) { + // par1 is countlim; par2 is nsigma + mode=NOISE_TRIMMING; + par1=500; + par2=4; + } else if (string(args[0]).find("beam")!=string::npos){ + // par1 is countlim; par2 is nsigma + mode=BEAM_TRIMMING; + par1=1000; + par2=4; + } else if (string(args[0]).find("improve")!=string::npos) { + // par1 is maxit; if par2!=0 vthresh will be optimized + mode=IMPROVE_TRIMMING; + par1=5; + par2=0; + } else if (string(args[0]).find("fix")!=string::npos) { + // par1 is countlim; if par2<0 then trimwithlevel else trim with median + mode=FIXEDSETTINGS_TRIMMING; + par1=1000; + par2=1; + // }else if (string(args[0]).find("fix")!=string::npos) { + //mode=OFFLINE_TRIMMING; + } else { + return string("Unknown trim mode ")+cmd; + } + myDet->executeTrimming(mode, par1, par2); + string sval=string(args[1]); + myDet->saveSettingsFile(sval, -1); + return string("done"); + + } else if (cmd=="trimval") { + if (action==PUT_ACTION){ + if (sscanf(args[1],"%d",&val)) + myDet->setAllTrimbits(val); + else + return string("invalid trimbit value ")+cmd; + } + sprintf(ans,"%d",myDet->setAllTrimbits(-1)); + return ans; + } else if (cmd=="pedestal") { + if (action==GET_ACTION) + return string("cannot get"); + if (sscanf(args[1],"%d",&val)){ + sprintf(ans,"%d",myDet->calibratePedestal(val)); + return string(ans); + }else + return string("cannot parse frame number")+cmd; + + } + return string("unknown settings command ")+cmd; + +} + + +string slsDetectorCommand::helpSettings(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "settings s \n sets the settings of the detector - can be standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain" + "lownoise, dynamichg0,fixgain1,fixgain2,forceswitchg1, forceswitchg2"<< std::endl; + os << "threshold eV\n sets the detector threshold in eV"<< std::endl; + os << "trimbits fname\n loads the trimfile fname to the detector. If no extension is specified, the serial number of each module will be attached."<< std::endl; + os << "trim:mode fname\n trims the detector according to mode (can be noise, beam, improve, fix) and saves the resulting trimbits to file fname."<< std::endl; + os << "trimval i \n sets all the trimbits to i" << std::endl; + os << "pedestal i \n starts acquisition for i frames, calculates pedestal and writes back to fpga."<< std::endl; + + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "settings \n gets the settings of the detector"<< std::endl; + os << "threshold V\n gets the detector threshold"<< std::endl; + os << "trimbits [fname]\n returns the trimfile loaded on the detector. If fname is specified the trimbits are saved to file. If no extension is specified, the serial number of each module will be attached."<< std::endl; + os << "trimval \n returns the value all trimbits are set to. If they are different, returns -1." << std::endl; + } + return os.str(); + + +} + + + + + + + + + + +string slsDetectorCommand::cmdSN(int narg, char *args[], int action) { + + char answer[1000]; + + + if (action==PUT_ACTION) + return string("cannot set"); + + + if (action==HELP_ACTION) + return helpSN(narg, args, action); + + + if (cmd=="thisversion"){ + sprintf(answer,"%llx",myDet->getId(THIS_SOFTWARE_VERSION)); + return string(answer); + } + + myDet->setOnline(ONLINE_FLAG); + + + if (cmd=="moduleversion") { + int ival=-1; + if (sscanf(args[0],"moduleversion:%d",&ival)) { + sprintf(answer,"%llx",myDet->getId(MODULE_FIRMWARE_VERSION,ival)); + return string(answer); + } else + return string("undefined module number"); + } + if (cmd=="detectornumber") { + sprintf(answer,"%llx",myDet->getId(DETECTOR_SERIAL_NUMBER)); + return string(answer); + } + if (cmd.find("modulenumber")!=string::npos) { + int ival=-1; + if (sscanf(args[0],"modulenumber:%d",&ival)) { + sprintf(answer,"%llx",myDet->getId(MODULE_SERIAL_NUMBER,ival)); + return string(answer); + } else + return string("undefined module number"); + } + + if (cmd=="detectorversion") { + sprintf(answer,"%llx",myDet->getId(DETECTOR_FIRMWARE_VERSION)); + return string(answer); + } + + if (cmd=="softwareversion") { + sprintf(answer,"%llx",myDet->getId(DETECTOR_SOFTWARE_VERSION)); + return string(answer); + } + + if (cmd=="receiverversion") { + sprintf(answer,"%llx",myDet->getId(RECEIVER_VERSION)); + return string(answer); + } + return string("unknown id mode ")+cmd; + +} + +string slsDetectorCommand::helpSN(int narg, char *args[], int action) { + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) { + os << "moduleversion:i \n gets the firmwareversion of the module i"<< std::endl; + os << "modulenumber:i \n gets the serial number of the module i"<< std::endl; + os << "detectornumber \n gets the serial number of the detector (MAC)"<< std::endl; + os << "detectorversion \n gets the firmware version of the detector"<< std::endl; + os << "softwareversion \n gets the software version of the detector"<< std::endl; + os << "thisversion \n gets the version of this software"<< std::endl; + os << "receiverversion \n gets the version of the receiver"<< std::endl; + } + return os.str(); + + + +} + + +string slsDetectorCommand::cmdDigiTest(int narg, char *args[], int action) { + + char answer[1000]; + + if (action==HELP_ACTION) + return helpSN(narg, args, action); + + + myDet->setOnline(ONLINE_FLAG); + + if (cmd=="bustest"){ + if (action==PUT_ACTION) + return string("cannot set ")+cmd; + sprintf(answer,"%x",myDet->digitalTest(DETECTOR_BUS_TEST)); + return string(answer); + } + + if (cmd=="digitest") { + if (action==PUT_ACTION) + return string("cannot set ")+cmd; + int ival=-1; + if (sscanf(args[0],"digitest:%d",&ival)) { + sprintf(answer,"%x",myDet->digitalTest(CHIP_TEST, ival)); + return string(answer); + } else + return string("undefined module number"); + } + + if (cmd=="digibittest") { + if (action==GET_ACTION) + return string("cannot get ")+cmd; + int ival=-1; + if (sscanf(args[1],"%d",&ival)) { + if((ival==0)||(ival==1)){ + sprintf(answer,"%x",myDet->digitalTest(DIGITAL_BIT_TEST,ival)); + return string(answer); + } + else + return string("Use only 0 or 1 to set/clear digital test bit\n"); + } else + return string("undefined number"); + } + + + return string("unknown digital test mode ")+cmd; + +} + +string slsDetectorCommand::helpDigiTest(int narg, char *args[], int action) { + + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) { + os << "digitaltest:i \t performs digital test of the module i. Returns 0 if succeeded, otherwise error mask."<< std::endl; + os << "bustest \t performs test of the bus interface between FPGA and embedded Linux system. Can last up to a few minutes."<< std::endl; + } + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "digibittest i\t will perform test which will plot the unique channel identifier, instead of data."<< std::endl; + } + return os.str(); +} + +string slsDetectorCommand::cmdRegister(int narg, char *args[], int action) { + + + if (action==HELP_ACTION) + return helpRegister(narg, args, action); + + int addr, val,n; + char answer[1000]; + + myDet->setOnline(ONLINE_FLAG); + + + // "reg" // + + // "setbit" // + + // "clearbit" // + + // "getbit" // + + + + if (action==PUT_ACTION) { + if (cmd=="getbit") + return string("Cannot put"); + + if(narg<3) { + if (cmd=="reg") + return string("wrong usage: should specify both address and value (hexadecimal fomat) "); + else + return string("wrong usage: should specify both address (hexadecimal fomat) and bit number"); + + } + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan address (hexadecimal fomat) ")+string(args[1]); + + + if (cmd=="reg") { + if (sscanf(args[2],"%x",&val)) + ; + else + return string("Could not scan value (hexadecimal fomat) ")+string(args[2]); + sprintf(answer,"%x",myDet->writeRegister(addr,val)); + } else if (cmd=="adcreg") { + if (sscanf(args[2],"%x",&val)) + ; + else + return string("Could not scan value (hexadecimal fomat) ")+string(args[2]); + sprintf(answer,"%x",myDet->writeAdcRegister(addr,val)); + } else { + + if (sscanf(args[2],"%d",&n)) + ; + else + return string("Could not scan bit number ")+string(args[2]); + + if (n<0 || n>31) + return string("Bit number out of range")+string(args[2]); + + if (cmd=="setbit") + sprintf(answer,"%x",myDet->writeRegister(addr,myDet->readRegister(addr)| 1<writeRegister(addr,myDet->readRegister(addr) & ~(1<readRegister(addr)); + + } + + if (cmd=="getbit") { + + if(narg<3) + return string("wrong usage: should specify both address (hexadecimal fomat) and bit number"); + + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan address (hexadecimal fomat) ")+string(args[1]); + + if (sscanf(args[2],"%d",&n)) + ; + else + return string("Could not scan bit number ")+string(args[2]); + + if (n<0 || n>31) + return string("Bit number out of range")+string(args[2]); + + + sprintf(answer,"%d",(myDet->readRegister(addr) >> n) & 1); + } + } + + return string(answer); + + +} + +string slsDetectorCommand::helpRegister(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "reg addr val \n writes the register addr with the value val"<< std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "reg addr \n reads the register addr"<< std::endl; + } + return os.str(); + + + +} + + +string slsDetectorCommand::cmdDAC(int narg, char *args[], int action) { + + if (action==HELP_ACTION) + return helpDAC(narg, args, action); + + dacIndex dac; + dacs_t val=-1; + char answer[1000]; + int mode=0; + + int idac=-1; + if (sscanf(args[0],"dac:%d",&idac)==1) { + printf("chiptestboard!\n"); + dac=(dacIndex)idac; + } + else if (cmd=="adcvpp") + dac=ADC_VPP; + else if (cmd=="vthreshold") + dac=THRESHOLD; + else if (cmd=="vcalibration") + dac=CALIBRATION_PULSE; + else if (cmd=="vtrimbit") + dac=TRIMBIT_SIZE; + else if (cmd=="vpreamp") + dac=PREAMP; + else if (cmd=="vshaper1") + dac=SHAPER1; + else if (cmd=="vshaper2") + dac=SHAPER2; + else if (cmd=="vhighvoltage") + dac=HV_NEW; + else if (cmd=="vapower") + dac=VA_POT; + else if (cmd=="vddpower") + dac=VDD_POT; + else if (cmd=="vshpower") + dac=VSH_POT; + else if (cmd=="viopower") + dac=VIO_POT; + else if (cmd=="vref_ds") + dac=G_VREF_DS; + else if (cmd=="vcascn_pb") + dac=G_VCASCN_PB; + else if (cmd=="vcascp_pb") + dac=G_VCASCP_PB; + else if (cmd=="vout_cm") + dac=G_VOUT_CM; + else if (cmd=="vcasc_out") + dac=G_VCASC_OUT; + else if (cmd=="vin_cm") + dac=G_VIN_CM; + else if (cmd=="vref_comp") + dac=G_VREF_COMP; + else if (cmd=="ib_test_c") + dac=G_IB_TESTC; + + else if (cmd=="dac0") + dac=V_DAC0; + else if (cmd=="dac1") + dac=V_DAC1; + else if (cmd=="dac2") + dac=V_DAC2; + else if (cmd=="dac3") + dac=V_DAC3; + else if (cmd=="dac4") + dac=V_DAC4; + else if (cmd=="dac5") + dac=V_DAC5; + else if (cmd=="dac6") + dac=V_DAC6; + else if (cmd=="dac7") + dac=V_DAC7; + + + + + else if (cmd== "vsvp") + dac=E_SvP; + else if (cmd=="vsvn") + dac=E_SvN; + else if (cmd=="vtr") + dac=E_Vtr; + else if (cmd=="vrf") + dac=E_Vrf; + else if (cmd=="vrs") + dac=E_Vrs; + else if (cmd== "vtgstv") + dac=E_Vtgstv; + else if (cmd== "vcmp_ll") + dac=E_Vcmp_ll; + else if (cmd=="vcmp_lr") + dac=E_Vcmp_lr; + else if (cmd== "vcall") + dac=E_cal; + else if (cmd== "vcmp_rl") + dac=E_Vcmp_rl; + else if (cmd== "vcmp_rr") + dac=E_Vcmp_rr; + else if (cmd== "rxb_rb") + dac=E_rxb_rb; + else if (cmd== "rxb_lb") + dac=E_rxb_lb; + else if (cmd== "vcp") + dac=E_Vcp; + else if (cmd=="vcn") + dac=E_Vcn; + else if (cmd== "vis") + dac=E_Vis; + else if (cmd== "iodelay") + dac=IO_DELAY; + else if (cmd== "v_a") + dac=V_POWER_A; + else if (cmd== "v_b") + dac=V_POWER_B; + else if (cmd== "v_c") + dac=V_POWER_C; + else if (cmd== "v_d") + dac=V_POWER_D; + else if (cmd== "v_io") + dac=V_POWER_IO; + else if (cmd== "v_chip") + dac=V_POWER_CHIP; + else + return string("cannot decode dac ")+cmd; + + myDet->setOnline(ONLINE_FLAG); + + if (action==PUT_ACTION) { + + if(narg >= 3) + if(!strcasecmp(args[2],"mv")) + mode = 1; +#ifdef DACS_INT + + if (sscanf(args[1],"%d", &val)) +#else + if (sscanf(args[1],"%f", &val)) +#endif + ; + else + return string("cannot scan DAC value ")+string(args[1]); + + myDet->setDAC(val,dac,mode); + } + + else if(narg >= 2) + if(!strcasecmp(args[1],"mv")) + mode = 1; + +#ifdef DACS_INT + sprintf(answer,"%d",myDet->setDAC(-1,dac,mode)); +#else + sprintf(answer,"%f",myDet->setDAC(-1,dac,mode)); +#endif + if(mode) + strcat(answer,"mV"); + return string(answer); + +} + + +string slsDetectorCommand::helpDAC(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "vthreshold dacu\t sets the detector threshold in dac units (0-1024) or mV. The energy is approx 800-15*keV" << std::endl; + os << std::endl; + + os << "vcalibration " << "dacu\t sets the calibration pulse amplitude in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vtrimbit " << "dacu\t sets the trimbit amplitude in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vpreamp " << "dacu\t sets the preamp feedback voltage in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vshaper1 " << "dacu\t sets the shaper1 feedback voltage in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vshaper2 " << "dacu\t sets the shaper2 feedback voltage in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vhighvoltage " << "dacu\t CHIPTEST BOARD ONLY - sets the detector HV in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vapower " << "dacu\t CHIPTEST BOARD ONLY - sets the analog power supply in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vddpower " << "dacu\t CHIPTEST BOARD ONLY - sets the digital power supply in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vshpower " << "dacu\t CHIPTEST BOARD ONLY - sets the comparator power supply in dac units (0-1024)." << std::endl; + os << std::endl; + os << "viopower " << "dacu\t CHIPTEST BOARD ONLY - sets the FPGA I/O power supply in dac units (0-1024)." << std::endl; + + + + os << "vrefds " << "dacu\t sets vrefds" << std::endl; + os << "vcascn_pb " << "dacu\t sets vcascn_pb" << std::endl; + os << "vcascp_pb " << "dacu\t sets vcascp_pb" << std::endl; + os << "vout_cm " << "dacu\t sets vout_cm" << std::endl; + os << "vin_cm " << "dacu\t sets vin_cm" << std::endl; + os << "vcasc_out " << "dacu\t sets vcasc_out" << std::endl; + os << "vref_comp " << "dacu\t sets vref_comp" << std::endl; + os << "ib_test_c " << "dacu\t sets ib_test_c" << std::endl; + + + os << "dac0 " << "dacu\t sets dac 0" << std::endl; + os << "dac1 " << "dacu\t sets dac 1" << std::endl; + os << "dac2 " << "dacu\t sets dac 2" << std::endl; + os << "dac3 " << "dacu\t sets dac 3" << std::endl; + os << "dac4 " << "dacu\t sets dac 4" << std::endl; + os << "dac5 " << "dacu\t sets dac 5" << std::endl; + os << "dac6 " << "dacu\t sets dac 6" << std::endl; + os << "dac7 " << "dacu\t sets dac 7" << std::endl; + + os << "vsvp" << "dacu\t sets vsvp" << std::endl; + os << "vsvn" << "dacu\t sets vsvn" << std::endl; + os << "vtr" << "dacu\t sets vtr" << std::endl; + os << "vrf" << "dacu\t sets vrf" << std::endl; + os << "vrs" << "dacu\t sets vrs" << std::endl; + os << "vtgstv" << "dacu\t sets vtgstv" << std::endl; + os << "vcmp_ll" << "dacu\t sets vcmp_ll" << std::endl; + os << "vcmp_lr" << "dacu\t sets vcmp_lr" << std::endl; + os << "vcall" << "dacu\t sets vcall" << std::endl; + os << "vcmp_rl" << "dacu\t sets vcmp_rl" << std::endl; + os << "vcmp_rr" << "dacu\t sets vcmp_rr" << std::endl; + os << "rxb_rb" << "dacu\t sets rxb_rb" << std::endl; + os << "rxb_lb" << "dacu\t sets rxb_lb" << std::endl; + os << "vcp" << "dacu\t sets vcp " << std::endl; + os << "vcn" << "dacu\t sets vcn " << std::endl; + os << "vis" << "dacu\t sets vis " << std::endl; + + + os << " mv if you want in mV else in dac units " << std::endl; + } + + if (action==GET_ACTION || action==HELP_ACTION) { + + os << "vthreshold \t Gets the detector threshold in dac units (0-1024). The energy is approx 800-15*keV" << std::endl; + os << std::endl; + + os << "vcalibration " << "dacu\t gets the calibration pulse amplitude in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vtrimbit " << "dacu\t gets the trimbit amplitude in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vpreamp " << "dacu\t gets the preamp feedback voltage in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vshaper1 " << "dacu\t gets the shaper1 feedback voltage in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vshaper2 " << "dacu\t gets the shaper2 feedback voltage in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vhighvoltage " << "dacu\t CHIPTEST BOARD ONLY - gets the detector HV in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vapower " << "dacu\t CHIPTEST BOARD ONLY - gets the analog power supply in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vddpower " << "dacu\t CHIPTEST BOARD ONLY - gets the digital power supply in dac units (0-1024)." << std::endl; + os << std::endl; + os << "vshpower " << "dacu\t CHIPTEST BOARD ONLY - gets the comparator power supply in dac units (0-1024)." << std::endl; + os << std::endl; + os << "viopower " << "dacu\t CHIPTEST BOARD ONLY - gets the FPGA I/O power supply in dac units (0-1024)." << std::endl; + os << std::endl; + + + os << "vrefds " << "\t gets vrefds" << std::endl; + os << "vcascn_pb " << "\t gets vcascn_pb" << std::endl; + os << "vcascp_pb " << "\t gets vcascp_pb" << std::endl; + os << "vout_cm " << "\t gets vout_cm" << std::endl; + os << "vin_cm " << "\t gets vin_cm" << std::endl; + os << "vcasc_out " << "\t gets vcasc_out" << std::endl; + os << "vref_comp " << "\t gets vref_comp" << std::endl; + os << "ib_test_c " << "\t gets ib_test_c" << std::endl; + + + os << "dac0 " << "\t gets dac 0" << std::endl; + os << "dac1 " << "\t gets dac 0" << std::endl; + os << "dac2 " << "\t gets dac 0" << std::endl; + os << "dac3 " << "\t gets dac 0" << std::endl; + os << "dac4 " << "\t gets dac 0" << std::endl; + os << "dac5 " << "\t gets dac 0" << std::endl; + os << "dac6 " << "\t gets dac 0" << std::endl; + os << "dac7 " << "\t gets dac 0" << std::endl; + + os << "vsvp" << "dacu\t gets vsvp" << std::endl; + os << "vsvn" << "dacu\t gets vsvn" << std::endl; + os << "vtr" << "dacu\t gets vtr" << std::endl; + os << "vrf" << "dacu\t gets vrf" << std::endl; + os << "vrs" << "dacu\t gets vrs" << std::endl; + os << "vtgstv" << "dacu\t gets vtgstv" << std::endl; + os << "vcmp_ll" << "dacu\t gets vcmp_ll" << std::endl; + os << "vcmp_lr" << "dacu\t gets vcmp_lr" << std::endl; + os << "vcall" << "dacu\t gets vcall" << std::endl; + os << "vcmp_rl" << "dacu\t gets vcmp_rl" << std::endl; + os << "vcmp_rr" << "dacu\t gets vcmp_rr" << std::endl; + os << "rxb_rb" << "dacu\t gets rxb_rb" << std::endl; + os << "rxb_lb" << "dacu\t gets rxb_lb" << std::endl; + os << "vcp" << "dacu\t gets vcp " << std::endl; + os << "vcn" << "dacu\t gets vcn " << std::endl; + os << "vis" << "dacu\t gets vis " << std::endl; + + + } + return os.str(); +} + + + +string slsDetectorCommand::cmdADC(int narg, char *args[], int action) { + + dacIndex adc; + // double val=-1; + char answer[1000]; + + if (action==HELP_ACTION) + return helpADC(narg, args, action); + else if (action==PUT_ACTION) + return string("cannot set ")+cmd; + + if (cmd=="temp_adc") + adc=TEMPERATURE_ADC; + else if (cmd=="temp_fpga") + adc=TEMPERATURE_FPGA; + else if (cmd=="temp_fpgaext") + adc=TEMPERATURE_FPGAEXT; + else if (cmd=="temp_10ge") + adc=TEMPERATURE_10GE; + else if (cmd=="temp_dcdc") + adc=TEMPERATURE_DCDC; + else if (cmd=="temp_sodl") + adc=TEMPERATURE_SODL; + else if (cmd=="temp_sodr") + adc=TEMPERATURE_SODR; + else if (cmd=="temp_fpgafl") + adc=TEMPERATURE_FPGA2; + else if (cmd=="temp_fpgafr") + adc=TEMPERATURE_FPGA3; + else + return string("cannot decode adc ")+cmd; + + myDet->setOnline(ONLINE_FLAG); +#ifdef DACS_INT + if (myDet->getDetectorsType() == EIGER) + sprintf(answer,"%.2f",(double)myDet->getADC(adc)/1000.00); + else sprintf(answer,"%d",myDet->getADC(adc)); +#else + sprintf(answer,"%f",myDet->getADC(adc)); +#endif + //if ((adc == TEMPERATURE_ADC) || (adc == TEMPERATURE_FPGA)) + strcat(answer,"°C"); + return string(answer); + +} + +string slsDetectorCommand::helpADC(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "temp_adc " << "Cannot be set" << std::endl; + os << "temp_fpga " << "Cannot be set" << std::endl; + os << "temp_fpgaext " << "Cannot be set" << std::endl; + os << "temp_10ge " << "Cannot be set" << std::endl; + os << "temp_dcdc " << "Cannot be set" << std::endl; + os << "temp_sodl " << "Cannot be set" << std::endl; + os << "temp_sodr " << "Cannot be set" << std::endl; + os << "temp_fpgafl " << "Cannot be set" << std::endl; + os << "temp_fpgafr " << "Cannot be set" << std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION) { + os << "temp_adc " << "\t gets the temperature of the adc" << std::endl; + os << "temp_fpga " << "\t gets the temperature of the fpga" << std::endl; + os << "temp_fpgaext " << "\t gets the temperature close to the fpga" << std::endl; + os << "temp_10ge " << "\t gets the temperature close to the 10GE" << std::endl; + os << "temp_dcdc " << "\t gets the temperature close to the dc dc converter" << std::endl; + os << "temp_sodl " << "\t gets the temperature close to the left so-dimm memory" << std::endl; + os << "temp_sodr " << "\t gets the temperature close to the right so-dimm memory" << std::endl; + os << "temp_fpgafl " << "\t gets the temperature of the left front end board fpga" << std::endl; + os << "temp_fpgafr " << "\t gets the temperature of the left front end board fpga" << std::endl; + } + return os.str(); +} + +string slsDetectorCommand::cmdTiming(int narg, char *args[], int action){ +#ifdef VERBOSE + cout << string("Executing command ")+string(args[0])+string(" ( ")+cmd+string(" )\n"); +#endif + + if (action==HELP_ACTION) { + return helpTiming(narg,args,HELP_ACTION); + } + myDet->setOnline(ONLINE_FLAG); + if (action==PUT_ACTION) { + if (myDet->externalCommunicationType(string(args[1]))== GET_EXTERNAL_COMMUNICATION_MODE) return helpTiming(narg,args, action); + myDet->setExternalCommunicationMode(myDet->externalCommunicationType(string(args[1]))); + } + return myDet->externalCommunicationType(myDet->setExternalCommunicationMode()); + +} +string slsDetectorCommand::helpTiming(int narg, char *args[], int action){ + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) + os << string("timing \t gets the timing mode of the detector (auto, trigger, ro_trigger, gating, triggered_gating)\n"); + if (action==PUT_ACTION || action==HELP_ACTION) + os << string("timing mode \t sets synchronization mode of the detector. Can be auto, trigger, ro_trigger, gating, triggered_gating \n"); + return os.str(); +} + + + +string slsDetectorCommand::cmdTimer(int narg, char *args[], int action) { + timerIndex index; + int64_t t=-1, ret; + double val, rval; + + char answer[1000]; + + + if (action==HELP_ACTION) + return helpTimer(narg, args, action); + + if (cmd=="exptime") + index=ACQUISITION_TIME; + else if (cmd=="subexptime") + index=SUBFRAME_ACQUISITION_TIME; + else if (cmd=="period") + index=FRAME_PERIOD; + else if (cmd=="delay") + index=DELAY_AFTER_TRIGGER; + else if (cmd=="gates") + index=GATES_NUMBER; + else if (cmd=="frames") + index=FRAME_NUMBER; + else if (cmd=="cycles") + index=CYCLES_NUMBER; + else if (cmd=="probes") + index=PROBES_NUMBER; + else if (cmd=="measurements") + index=MEASUREMENTS_NUMBER; + else + return string("could not decode timer ")+cmd; + + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%lf", &val)) + ; + else + return string("cannot scan timer value ")+string(args[1]); + if (index==ACQUISITION_TIME || index==SUBFRAME_ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER) + t=(int64_t)(val*1E+9); + else t=(int64_t)val; + } + + + myDet->setOnline(ONLINE_FLAG); + + ret=myDet->setTimer(index,t); + if (index==ACQUISITION_TIME || index==SUBFRAME_ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER) + rval=(double)ret*1E-9; + else rval=ret; + + //set frame index + if (index==FRAME_NUMBER || index==CYCLES_NUMBER ){ + if ((myDet->setTimer(FRAME_NUMBER,-1)*myDet->setTimer(CYCLES_NUMBER,-1))>1) + myDet->setFrameIndex(0); + else + myDet->setFrameIndex(-1); + } + + + sprintf(answer,"%0.9f",rval); + return string(answer); + + + + +} + + +string slsDetectorCommand::helpTimer(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "exptime t \t sets the exposure time in s" << std::endl; + os << "subexptime t \t sets the exposure time of subframe in s" << std::endl; + os << "period t \t sets the frame period in s" << std::endl; + os << "delay t \t sets the delay after trigger in s" << std::endl; + os << "frames t \t sets the number of frames per cycle (e.g. after each trigger)" << std::endl; + os << "cycles t \t sets the number of cycles (e.g. number of triggers)" << std::endl; + os << "probes t \t sets the number of probes to accumulate (max 3! cycles should be set to 1, frames to the number of pump-probe events)" << std::endl; + os << std::endl; + + + } + if (action==GET_ACTION || action==HELP_ACTION) { + + os << "exptime \t gets the exposure time in s" << std::endl; + os << "subexptime \t gets the exposure time of subframe in s" << std::endl; + os << "period \t gets the frame period in s" << std::endl; + os << "delay \t gets the delay after trigger in s" << std::endl; + os << "frames \t gets the number of frames per cycle (e.g. after each trigger)" << std::endl; + os << "cycles \t gets the number of cycles (e.g. number of triggers)" << std::endl; + os << "probes \t gets the number of probes to accumulate" << std::endl; + os << std::endl; + + } + return os.str(); + + + + + + + + +} + + +string slsDetectorCommand::cmdTimeLeft(int narg, char *args[], int action) { + timerIndex index; + int64_t ret; + double rval; + + char answer[1000]; + + + if (action==HELP_ACTION) + return helpTimeLeft(narg, args, action); + + if (cmd=="exptimel") + index=ACQUISITION_TIME; + else if (cmd=="periodl") + index=FRAME_PERIOD; + else if (cmd=="delayl") + index=DELAY_AFTER_TRIGGER; + else if (cmd=="gatesl") + index=GATES_NUMBER; + else if (cmd=="framesl") + index=FRAME_NUMBER; + else if (cmd=="cyclesl") + index=CYCLES_NUMBER; + else if (cmd=="probesl") + index=PROBES_NUMBER; + else if (cmd=="now") + index=ACTUAL_TIME; + else if (cmd=="timestamp") + index=MEASUREMENT_TIME; + else if (cmd=="nframes") + index=FRAMES_FROM_START; + else + return string("could not decode timer ")+cmd; + + + if (action==PUT_ACTION) { + return string("cannot set ")+string(args[1]); + } + + + + + myDet->setOnline(ONLINE_FLAG); + + ret=myDet->getTimeLeft(index); + + if (index==ACQUISITION_TIME || index==FRAME_PERIOD || index==DELAY_AFTER_TRIGGER || index==ACTUAL_TIME || index==MEASUREMENT_TIME) + rval=(double)ret*1E-9; + else rval=ret; + + + sprintf(answer,"%0.9f",rval); + return string(answer); + + + + + +} + + +string slsDetectorCommand::helpTimeLeft(int narg, char *args[], int action) { + + + + ostringstream os; + if (action==GET_ACTION || action==HELP_ACTION) { + + os << "exptimel \t gets the exposure time left" << std::endl; + os << "periodl \t gets the frame period left" << std::endl; + os << "delayl \t gets the delay left" << std::endl; + os << "framesl \t gets the number of frames left" << std::endl; + os << "cyclesl \t gets the number of cycles left" << std::endl; + os << "probesl \t gets the number of probes left" << std::endl; + os << std::endl; + + } + return os.str(); + + + + +} + + + + + + + +string slsDetectorCommand::cmdSpeed(int narg, char *args[], int action) { + + speedVariable index; + int t=-1, ret; + + char answer[1000]; + + + if (action==HELP_ACTION) + return helpSpeed(narg, args, action); + + if (cmd=="clkdivider") + index=CLOCK_DIVIDER; + else if (cmd=="setlength") + index=SET_SIGNAL_LENGTH; + else if (cmd=="waitstates") + index=WAIT_STATES; + else if (cmd=="totdivider") + index=TOT_CLOCK_DIVIDER; + else if (cmd=="totdutycycle") + index=TOT_DUTY_CYCLE; + else if (cmd=="phasestep") { + index=PHASE_SHIFT; + t=100000; + } else if (cmd=="oversampling") + index=OVERSAMPLING; + else if (cmd=="adcclk") + index=ADC_CLOCK; + else if (cmd=="adcphase") { + index=ADC_PHASE; + t=100000; + } else if (cmd=="adcpipeline") + index=ADC_PIPELINE; + else + return string("could not decode speed variable ")+cmd; + + + if (action==PUT_ACTION) { + if (sscanf(args[1],"%d", &t)) + ; + else + return string("cannot scan speed value ")+string(args[1]); + + } + + myDet->setOnline(ONLINE_FLAG); + + ret=myDet->setSpeed(index,t); + + sprintf(answer,"%d",ret); + return string(answer); + + + + +} + + +string slsDetectorCommand::helpSpeed(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + + os << "clkdivider c \t sets readout clock divider" << std::endl; + os << "setlength c\t sets the length of the set/reset signals (in clock cycles)" << std::endl; + os << "waitstates c \t sets the waitstates of the bus interface" << std::endl; + os << "totdivider c\t sets the clock divider in tot mode" << std::endl; + os << "totdutycycle c\t sets the duty cycle of the tot clock" << std::endl; + os << std::endl; + + } + if (action==GET_ACTION || action==HELP_ACTION) { + + os << "clkdivider \t gets readout clock divider" << std::endl; + os << "setlength \t gets the length of the set/reset signals (in clock cycles)" << std::endl; + os << "waitstates \t gets the waitstates of the bus interface" << std::endl; + os << "totdivider \t gets the clock divider in tot mode" << std::endl; + os << "totdutycycle \t gets the duty cycle of the tot clock" << std::endl; + os << std::endl; + + } + return os.str(); + + + + + + + + +} + + + + +string slsDetectorCommand::cmdAdvanced(int narg, char *args[], int action) { + +int retval; +char answer[1000]=""; + + if (action==HELP_ACTION) + return helpAdvanced(narg, args, action); + + if (cmd=="flags") { + + readOutFlags flag=GET_READOUT_FLAGS; + + if (action==PUT_ACTION) { + string sval=string(args[1]); + if (sval=="none") + flag=NORMAL_READOUT; + else if (sval=="storeinram") + flag=STORE_IN_RAM; + else if (sval=="tot") + flag=TOT_MODE; + else if (sval=="continous") + flag=CONTINOUS_RO; + else if (sval=="parallel") + flag=PARALLEL; + else if (sval=="nonparallel") + flag=NONPARALLEL; + else if (sval=="safe") + flag=SAFE; + else + return string("could not scan flag ")+string(args[1]); + } + + + myDet->setOnline(ONLINE_FLAG); + + retval = myDet->setReadOutFlags(flag); + + if(retval == NORMAL_READOUT) + return string("none"); + + if(retval & STORE_IN_RAM) + strcat(answer,"storeinram "); + if(retval & TOT_MODE) + strcat(answer,"tot "); + if(retval & CONTINOUS_RO) + strcat(answer,"continous "); + if(retval & PARALLEL) + strcat(answer,"parallel "); + if(retval & NONPARALLEL) + strcat(answer,"nonparallel "); + if(retval & SAFE) + strcat(answer,"safe "); + if(strlen(answer)) + return string(answer); + + return string("unknown"); + + } else if (cmd=="extsig") { + externalSignalFlag flag=GET_EXTERNAL_SIGNAL_FLAG; + int is=-1; + if (sscanf(args[0],"extsig:%d",&is)) + ; + else + return string("could not scan signal number ")+string(args[0]); + + if (action==PUT_ACTION) { + flag=myDet->externalSignalType(args[1]); + if (flag==GET_EXTERNAL_SIGNAL_FLAG) + return string("could not scan external signal mode ")+string(args[1]); + } + myDet->setOnline(ONLINE_FLAG); + + return myDet->externalSignalType(myDet->setExternalSignalFlags(flag,is)); + + } else + return string("could not decode flag ")+cmd; + +} + + +string slsDetectorCommand::helpAdvanced(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + + os << "extsig:i mode \t sets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl; + os << "flags mode \t sets the readout flags to mode. can be none, storeinram, tot, continous, parallel, nonparallel, safe, unknown" << std::endl; + + } + if (action==GET_ACTION || action==HELP_ACTION) { + + os << "extsig:i \t gets the mode of the external signal i. can be \n \t \t \t off, \n \t \t \t gate_in_active_high, \n \t \t \t gate_in_active_low, \n \t \t \t trigger_in_rising_edge, \n \t \t \t trigger_in_falling_edge, \n \t \t \t ro_trigger_in_rising_edge, \n \t \t \t ro_trigger_in_falling_edge, \n \t \t \t gate_out_active_high, \n \t \t \t gate_out_active_low, \n \t \t \t trigger_out_rising_edge, \n \t \t \t trigger_out_falling_edge, \n \t \t \t ro_trigger_out_rising_edge, \n \t \t \t ro_trigger_out_falling_edge" << std::endl; + os << "flags \t gets the readout flags. can be none, storeinram, tot, continous, parallel, nonparallel, safe, unknown" << std::endl; + + } + return os.str(); + + + + + + + + +} + + + + +string slsDetectorCommand::cmdConfiguration(int narg, char *args[], int action) { + + + + if (action==HELP_ACTION) + return helpConfiguration(narg, args, action); + + string sval; + + if (narg<2 && cmd != "rx_printconfig") + return string("should specify I/O file"); + + myDet->setOnline(ONLINE_FLAG); + + if (cmd=="config") { + if (action==PUT_ACTION) { + sval=string(args[1]); + myDet->readConfigurationFile(sval); + } else if (action==GET_ACTION) { + sval=string(args[1]); + myDet->writeConfigurationFile(sval); + } + return sval; + } else if (cmd=="rx_printconfig"){ + if (action==PUT_ACTION) + return string("cannot put"); + return string(""+myDet->printReceiverConfiguration()); + }else if (cmd=="parameters") { + if (action==PUT_ACTION) { + sval=string(args[1]); + myDet->retrieveDetectorSetup(sval); + } else if (action==GET_ACTION) { + sval=string(args[1]); + myDet->dumpDetectorSetup(sval); + } + return sval; + } else if (cmd=="setup") { + if (action==PUT_ACTION) { + sval=string(args[1]); + myDet->retrieveDetectorSetup(sval,2); + } else if (action==GET_ACTION) { + sval=string(args[1]); + myDet->dumpDetectorSetup(sval,2); + } + return sval; + } + return string("could not decode conf mode"); + + +} + + +string slsDetectorCommand::helpConfiguration(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + + os << "config fname \t sets the detector to the configuration contained in fname" << std::endl; + os << "parameters fname \t sets the detector parameters to those contained in fname" << std::endl; + os << "setup fname \t sets the detector complete detector setup to that contained in fname (extensions automatically generated), including trimfiles, ff coefficients etc." << std::endl; + + } + if (action==GET_ACTION || action==HELP_ACTION) { + + os << "config fname \t saves the detector to the configuration to fname" << std::endl; + os << "parameters fname \t saves the detector parameters to fname" << std::endl; + os << "setup fname \t saves the detector complete detector setup to fname (extensions automatically generated), including trimfiles, ff coefficients etc." << std::endl; + + } + + return os.str(); + + + + + + + + +} + + +string slsDetectorCommand::cmdReceiver(int narg, char *args[], int action) { + char answer[100]; + int ival = -1; + + if (action==HELP_ACTION) + return helpReceiver(narg, args, action); + + + myDet->setOnline(ONLINE_FLAG); + + if(cmd=="receiver"){ + if (action==PUT_ACTION) { + if(!strcasecmp(args[1],"start")) + myDet->startReceiver(); + else if(!strcasecmp(args[1],"stop")){ + myDet->startReceiverReadout(); + /*runStatus s = myDet->getReceiverStatus(); + while(s != RUN_FINISHED){ + usleep(50000); + s = myDet->getReceiverStatus(); + }*/ + myDet->stopReceiver(); + } + else + return helpReceiver(narg, args, action); + } + return myDet->runStatusType(myDet->getReceiverStatus()); + } + + + else if(cmd=="framescaught"){ + if (action==PUT_ACTION) + return string("cannot put"); + else{ + sprintf(answer,"%d",myDet->getFramesCaughtByReceiver()); + return string(answer); + } + } + + else if(cmd=="resetframescaught"){ + if (action==GET_ACTION) + return string("cannot get"); + else{ + if(myDet->resetFramesCaught() == FAIL) + strcpy(answer,"failed"); + else + strcpy(answer,"successful"); + return string(answer); + } + } + + else if(cmd=="frameindex"){ + if (action==PUT_ACTION) + return string("cannot put"); + else{ + sprintf(answer,"%d",myDet->getReceiverCurrentFrameIndex()); + return string(answer); + } + } + else if(cmd=="r_readfreq"){ + if (action==PUT_ACTION){ + if (!sscanf(args[1],"%d",&ival)) + return string("Could not scan read frequency mode ")+string(args[1]); + if(ival>=0) + myDet->setReadReceiverFrequency(1,ival); + } + sprintf(answer,"%d",myDet->setReadReceiverFrequency(1)); + return string(answer); + + } + else if(cmd=="r_compression"){ + if (action==PUT_ACTION){ + if (!sscanf(args[1],"%d",&ival)) + return string("Could not scan receiver compression input ")+string(args[1]); + if(ival>=0) + sprintf(answer,"%d",myDet->enableReceiverCompression(ival)); + }else + sprintf(answer,"%d",myDet->enableReceiverCompression()); + return string(answer); + + } + + else if(cmd=="tengiga"){ + if (action==PUT_ACTION){ + if (!sscanf(args[1],"%d",&ival)) + return string("Could not scan tengiga input ")+string(args[1]); + if(ival>=0) + sprintf(answer,"%d",myDet->enableTenGigabitEthernet(ival)); + }else + sprintf(answer,"%d",myDet->enableTenGigabitEthernet()); + return string(answer); + + } + + + else if(cmd=="rx_fifodepth"){ + if (action==PUT_ACTION){ + if (!sscanf(args[1],"%d",&ival)) + return string("Could not scan rx_fifodepth input ")+string(args[1]); + if(ival>=0) + sprintf(answer,"%d",myDet->setReceiverFifoDepth(ival)); + }else + sprintf(answer,"%d",myDet->setReceiverFifoDepth()); + return string(answer); + + } + + return string("could not decode command"); + +} + + + +string slsDetectorCommand::helpReceiver(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "receiver [status] \t starts/stops the receiver to listen to detector packets. - can be start or stop" << std::endl; + os << "resetframescaught [any value] \t resets frames caught by receiver" << std::endl; + os << "r_readfreq \t sets the gui read frequency of the receiver, 0 if gui requests frame, >0 if receiver sends every nth frame to gui" << std::endl; + os << "tengiga \t sets system to be configure for 10Gbe if set to 1, else 1Gbe if set to 0" << std::endl; + os << "rx_fifodepth [val]\t sets receiver fifo depth to val" << std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION){ + os << "receiver \t returns the status of receiver - can be running or idle" << std::endl; + os << "framescaught \t returns the number of frames caught by receiver(average for multi)" << std::endl; + os << "frameindex \t returns the current frame index of receiver(average for multi)" << std::endl; + os << "r_readfreq \t returns the gui read frequency of the receiver" << std::endl; + os << "tengiga \t returns 1 if the system is configured for 10Gbe else 0 for 1Gbe" << std::endl; + os << "rx_fifodepth \t returns receiver fifo depth" << std::endl; + } + return os.str(); + + + + + + + + +} + +string slsDetectorCommand::helpPattern(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "pattern fname \t loads pattern file" << std::endl; + os << "patword addr word \t writes pattern word - only very advanced users!" << std::endl; + os << "patioctrl reg\t configures inputs/outputs of the chiptest board - only advanced users!" << std::endl; + os << "patclkctrl reg\t configures output clk enable of the chiptest board- only advanced users! " << std::endl; + os << "patlimits addr1 addr2\t defines pattern limits between addr1 and addr2" << std::endl; + os << "patloop0 addr1 adrr2 \t configures the limits of the 0 loop " << std::endl; + os << "patloop1 addr1 adrr2 \t configures the limits of the 1 loop " << std::endl; + os << "patloop2 addr1 adrr2 \t configures the limits of the 2 loop " << std::endl; + os << "patnloop0 n \t sets number of cycles of the 0 loop " << std::endl; + os << "patnloop1 n \t sets number of cycles of the 1 loop " << std::endl; + os << "patnloop2 n \t sets number of cycles of the 2 loop " << std::endl; + os << "patwait0 addr \t configures pattern wait 0 address " << std::endl; + os << "patwait1 addr \t configures pattern wait 1 address " << std::endl; + os << "patwait2 addr \t configures pattern wait 2 address " << std::endl; + os << "patwaittime0 nclk \t sets wait 0 waiting time in clock number " << std::endl; + os << "patwaittime1 nclk \t sets wait 1 waiting time in clock number " << std::endl; + os << "patwaittime2 nclk \t sets wait 2 waiting time in clock number " << std::endl; + os << "adcinvert mask\t sets the adcinversion mask (hex)" << std::endl; + os << "adcdisable mask\t sets the adcdisable mask (hex)" << std::endl; + + } + if (action==GET_ACTION || action==HELP_ACTION){ + os << "pattern \t cannot get" << std::endl; + os << "patword \t cannot get" << std::endl; + os << "patioctrl \t returns inputs/outputs of the chiptest board - only advanced users!" << std::endl; + os << "patclkctrl\t returns output clk enable of the chiptest board- only advanced users! " << std::endl; + os << "patlimits \t returns pattern limits between addr1 and addr2" << std::endl; + os << "patloop0 \t returns the limits of the 0 loop " << std::endl; + os << "patloop1 \t returns the limits of the 1 loop " << std::endl; + os << "patloop2 \t returns the limits of the 2 loop " << std::endl; + os << "patnloop0 \t returns the number of cycles of the 0 loop " << std::endl; + os << "patnloop1 \t returns the number of cycles of the 1 loop " << std::endl; + os << "patnloop2 \t returns the number of cycles of the 2 loop " << std::endl; + os << "patwait0 \t returns the pattern wait 0 address " << std::endl; + os << "patwait1 \t returns the pattern wait 1 address " << std::endl; + os << "patwait2 \t returns the pattern wait 2 address " << std::endl; + os << "patwaittime0 \t returns the wait 0 waiting time in clock number " << std::endl; + os << "patwaittime1 \t returns the wait 1 waiting time in clock number " << std::endl; + os << "patwaittime2 \t returns the wait 2 waiting time in clock number " << std::endl; + os << "adcinvert \t returns the adcinversion mask " << std::endl; + + os << "adcdisable \t returns the adcdisable mask " << std::endl; + + } + return os.str(); + +} + + +string slsDetectorCommand::cmdPattern(int narg, char *args[], int action) { + + + if (action==HELP_ACTION) + return helpPattern(narg, args, action); + /******** + + Must implement set ctb functions in slsDetector and multiSlsDetector + + **********/ + string fname; + int addr, start, stop, n; + uint64_t word, t; + + myDet->setOnline(ONLINE_FLAG); + + ostringstream os; + if (cmd=="pattern") { + //get fname fron stdin + + if (action==PUT_ACTION) { + fname=string(args[1]); + os << myDet->setCTBPattern(fname); + } else if (action==GET_ACTION) + os << "Cannot get"; + } else if (cmd=="patword") { + + if (action==PUT_ACTION) { + //get addr, word from stdin + + if(narg<3) + return string("wrong usage: should specify both address and value (hexadecimal fomat) "); + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan address (hexadecimal fomat) ")+string(args[1]); + + if (sscanf(args[2],"%llx",&word)) + ; + else + return string("Could not scan value (hexadecimal fomat) ")+string(args[2]); + + + os << hex << myDet->setCTBWord(addr,word) << dec; + } else if (action==GET_ACTION) + os << "Cannot get"; + + + } else if (cmd=="patioctrl") { + //get word from stdin + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%llx",&word)) + ; + else + return string("Could not scan value (hexadecimal fomat) ")+string(args[1]); + + + myDet->setCTBWord(-1,word); + } + + os << hex << myDet->setCTBWord(-1,-1) << dec; + } else if (cmd=="patclkctrl") { + //get word from stdin + + + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%llx",&word)) + ; + else + return string("Could not scan value (hexadecimal fomat) ")+string(args[1]); + + + myDet->setCTBWord(-2,word); + } + + os << hex << myDet->setCTBWord(-2,-1) << dec; + + + } else if (cmd=="patlimits") { + //get start, stop from stdin + if (action==PUT_ACTION) { + if(narg<3) return string("wrong usage: should specify both start and stop address (hexadecimal fomat) "); + n=-1; + if (sscanf(args[1],"%x",&start)) + ; + else + return string("Could not scan start address (hexadecimal fomat) ")+string(args[1]); + + + if (sscanf(args[2],"%x",&stop)) + ; + else + return string("Could not scan stop address (hexadecimal fomat) ")+string(args[2]); + + myDet->setCTBPatLoops(-1,start, stop,n); + } + + start=-1; + stop=-1; + n=-1; + myDet->setCTBPatLoops(-1,start, stop,n); + os << hex << start << " " << stop;// << " "<< dec << n ; + } else if (cmd=="patloop0") { + //get start, stop from stdin + + + //get start, stop from stdin + if (action==PUT_ACTION) { + if(narg<3) return string("wrong usage: should specify both start and stop address (hexadecimal fomat) "); + n=-1; + if (sscanf(args[1],"%x",&start)) + ; + else + return string("Could not scan start address (hexadecimal fomat) ")+string(args[1]); + + + if (sscanf(args[2],"%x",&stop)) + ; + else + return string("Could not scan stop address (hexadecimal fomat) ")+string(args[2]); + + myDet->setCTBPatLoops(0,start, stop,n); + } + + start=-1; + stop=-1; + n=-1; + myDet->setCTBPatLoops(0,start, stop,n); + os << hex << start << " " << stop;// << " "<< dec << n ; + + + } else if (cmd=="patloop1") { + + //get start, stop from stdin + if (action==PUT_ACTION) { + if(narg<3) return string("wrong usage: should specify both start and stop address (hexadecimal fomat) "); + n=-1; + if (sscanf(args[1],"%x",&start)) + ; + else + return string("Could not scan start address (hexadecimal fomat) ")+string(args[1]); + + + if (sscanf(args[2],"%x",&stop)) + ; + else + return string("Could not scan stop address (hexadecimal fomat) ")+string(args[2]); + + myDet->setCTBPatLoops(1,start, stop,n); + } + + start=-1; + stop=-1; + n=-1; + myDet->setCTBPatLoops(1,start, stop,n); + os << hex << start << " " << stop;// << " "<< dec << n ; + + + + + } else if (cmd=="patloop2") { + + //get start, stop from stdin + if (action==PUT_ACTION) { + if(narg<3) return string("wrong usage: should specify both start and stop address (hexadecimal fomat) "); + n=-1; + if (sscanf(args[1],"%x",&start)) + ; + else + return string("Could not scan start address (hexadecimal fomat) ")+string(args[1]); + + + if (sscanf(args[2],"%x",&stop)) + ; + else + return string("Could not scan stop address (hexadecimal fomat) ")+string(args[2]); + + myDet->setCTBPatLoops(2,start, stop,n) ; + } + + start=-1; + stop=-1; + n=-1; + myDet->setCTBPatLoops(2,start, stop,n); + os << hex << start << " " << stop << dec;// << " "<< dec << n ; + + + } else if (cmd=="patnloop0") { + start=-1; + stop=-1; + + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%d",&n)) + ; + else + return string("Could not scan number of loops ")+string(args[1]); + + + myDet->setCTBPatLoops(0,start, stop,n) ; + } + + + + start=-1; + stop=-1; + n=-1; + myDet->setCTBPatLoops(0,start, stop,n); + os << n ; + } else if (cmd=="patnloop1") { + + + start=-1; + stop=-1; + + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%d",&n)) + ; + else + return string("Could not scan number of loops ")+string(args[1]); + + + myDet->setCTBPatLoops(1,start, stop,n) ; + } + + + + start=-1; + stop=-1; + n=-1; + myDet->setCTBPatLoops(1,start, stop,n); + os << n ; + + + + + } else if (cmd=="patnloop2") { + + + start=-1; + stop=-1; + + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%d",&n)) + ; + else + return string("Could not scan number of loops ")+string(args[1]); + + + myDet->setCTBPatLoops(2,start, stop,n) ; + } + + + + start=-1; + stop=-1; + n=-1; + myDet->setCTBPatLoops(2,start, stop,n); + os << n ; + + + + } else if (cmd=="patwait0") { + + + + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan wait address (hex format)")+string(args[1]); + + + myDet->setCTBPatWaitAddr(0,addr); + } + + + + os << hex << myDet->setCTBPatWaitAddr(0,-1) << dec; + + + + + + + } else if (cmd=="patwait1") { + + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan wait address (hex format)")+string(args[1]); + + + myDet->setCTBPatWaitAddr(1,addr); + } + + + + os << hex << myDet->setCTBPatWaitAddr(1,-1) << dec; + + + + } else if (cmd=="patwait2") { + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan wait address (hex format)")+string(args[1]); + + + myDet->setCTBPatWaitAddr(2,addr); + } + + + + os << hex << myDet->setCTBPatWaitAddr(2,-1) << dec ; + + } else if (cmd=="patwaittime0") { + + + + + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%lld",&t)) + ; + else + return string("Could not scan wait time")+string(args[1]); + + + myDet->setCTBPatWaitTime(0,t); + } + + + + os << myDet->setCTBPatWaitTime(0,-1); + + + + + + + + } else if (cmd=="patwaittime1") { + + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%lld",&t)) + ; + else + return string("Could not scan wait time ")+string(args[1]); + + + myDet->setCTBPatWaitTime(1,t); + } + + + + os << myDet->setCTBPatWaitTime(1,-1); + + + + } else if (cmd=="patwaittime2") { + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%lld",&t)) + ; + else + return string("Could not scan wait time ")+string(args[1]); + + + myDet->setCTBPatWaitTime(2,t); + } + + + + os << myDet->setCTBPatWaitTime(2,-1); + + } else if (cmd=="adcinvert") { + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan adcinvert reg ")+string(args[1]); + + + myDet->writeRegister(67,addr); + } + + + + os << hex << myDet->readRegister(67) << dec; + + } else if (cmd=="adcdisable") { + if (action==PUT_ACTION) { + + if (sscanf(args[1],"%x",&addr)) + ; + else + return string("Could not scan adcdisable reg ")+string(args[1]); + + + myDet->writeRegister(94,addr); + } + + + + os << hex << myDet->readRegister(94) << dec; + + } + + + +else return helpPattern(narg, args, action); + + + + + + return os.str(); + +} + + + +string slsDetectorCommand::helpPulse(int narg, char *args[], int action) { + + ostringstream os; + if (action==PUT_ACTION || action==HELP_ACTION) { + os << "pulse [n] [x] [y] \t pulses pixel at coordinates (x,y) n number of times" << std::endl; + os << "pulsenmove [n] [x] [y]\t pulses pixel n number of times and moves relatively by x value (x axis) and y value(y axis)" << std::endl; + os << "pulsechip [n] \t pulses chip n number of times, while n=-1 will reset it to normal mode" << std::endl; + } + if (action==GET_ACTION || action==HELP_ACTION){ + os << "pulse \t cannot get" << std::endl; + os << "pulsenmove \t cannot get" << std::endl; + os << "pulsechip \t cannot get" << std::endl; + } + return os.str(); + +} + + +string slsDetectorCommand::cmdPulse(int narg, char *args[], int action) { + int retval = FAIL; + + if (action==HELP_ACTION) + return helpPulse(narg, args, action); + else if (action==GET_ACTION) + return string("cannot get ")+cmd; + + myDet->setOnline(ONLINE_FLAG); + + + int ival1=-1; + if (!sscanf(args[1],"%d",&ival1)) + return string("Could not scan 1st argument ")+string(args[1]); + + if (string(args[0])==string("pulsechip")) + retval = myDet->pulseChip(ival1); + + + else{ + //next commands requires 3 addnl. arguments + int ival2=-1,ival3=-1; + if(narg<4) + return string("insufficient arguments:\n" + helpPulse(narg, args, action)); + if (!sscanf(args[2],"%d",&ival2)) + return string("Could not scan 2nd argument ")+string(args[2]); + if (!sscanf(args[3],"%d",&ival3)) + return string("Could not scan 3rd argument ")+string(args[3]); + + + if (string(args[0])==string("pulse")) + retval = myDet->pulsePixel(ival1,ival2,ival3); + + else if (string(args[0])==string("pulsenmove")) + retval = myDet->pulsePixelNMove(ival1,ival2,ival3); + + else return string("could not decode command")+cmd; + + } + + return string(""); +/* + if(retval == OK) + return string(" successful"); + else + return string(" failed"); + */ +} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/slsDetectorSoftware/slsDetector/slsDetectorCommand.h b/slsDetectorSoftware/slsDetector/slsDetectorCommand.h new file mode 100644 index 000000000..454e01f9f --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetectorCommand.h @@ -0,0 +1,188 @@ + +#ifndef SLS_DETECTOR_COMMAND_H +#define SLS_DETECTOR_COMMAND_H + + +#include "sls_detector_defs.h" +#include "slsDetectorUtils.h" +using namespace std; + + +/** @short This class handles the command line I/Os, help etc. of the text clients */ + + +class slsDetectorCommand : public virtual slsDetectorDefs { + + public: + + + slsDetectorCommand(slsDetectorUtils *det); + virtual ~slsDetectorCommand(){}; + + /* /\** */ + /* executes a set of string arguments according to a given format. It is used to read/write configuration file, dump and retrieve detector settings and for the command line interface command parsing */ + /* \param narg number of arguments */ + /* \param args array of string arguments */ + /* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ + /* \returns answer string */ + /* *\/ */ + virtual string executeLine(int narg, char *args[], int action); + + /* /\** */ + /* returns the help for the executeLine command */ + /* \param os output stream to return the help to */ + /* \param action can be PUT_ACTION or GET_ACTION (from text client even READOUT_ACTION for acquisition) */ + /* *\/ */ + string helpLine(int narg, char *args[], int action=HELP_ACTION); + static string helpAcquire(int narg, char *args[], int action); + static string helpData(int narg, char *args[], int action); + static string helpFrame(int narg, char *args[], int action); + static string helpStatus(int narg, char *args[], int action); + static string helpFree(int narg, char *args[], int action); + static string helpAdd(int narg, char *args[], int action); + static string helpRemove(int narg, char *args[], int action); + static string helpHostname(int narg, char *args[], int action); + static string helpId(int narg, char *args[], int action); + static string helpMaster(int narg, char *args[], int action); + static string helpSync(int narg, char *args[], int action); + static string helpExitServer(int narg, char *args[], int action); + static string helpSettingsDir(int narg, char *args[], int action); + static string helpCalDir(int narg, char *args[], int action); + static string helpTrimEn(int narg, char *args[], int action); + static string helpOutDir(int narg, char *args[], int action); + static string helpFileName(int narg, char *args[], int action); + static string helpFileIndex(int narg, char *args[], int action); + static string helpFlatField(int narg, char *args[], int action); + static string helpRateCorr(int narg, char *args[], int action); + static string helpBadChannels(int narg, char *args[], int action); + static string helpAngConv(int narg, char *args[], int action); + static string helpThreaded(int narg, char *args[], int action); + static string helpPositions(int narg, char *args[], int action); + static string helpScripts(int narg, char *args[], int action); + static string helpScans(int narg, char *args[], int action); + static string helpNetworkParameter(int narg, char *args[], int action); + static string helpPort(int narg, char *args[], int action); + static string helpLock(int narg, char *args[], int action); + static string helpLastClient(int narg, char *args[], int action); + static string helpOnline(int narg, char *args[], int action); + static string helpConfigureMac(int narg, char *args[], int action); + static string helpDetectorSize(int narg, char *args[], int action); + static string helpSettings(int narg, char *args[], int action); + static string helpSN(int narg, char *args[], int action); + static string helpDigiTest(int narg, char *args[], int action); + static string helpRegister(int narg, char *args[], int action); + static string helpDAC(int narg, char *args[], int action); + static string helpTimer(int narg, char *args[], int action); + static string helpTiming(int narg, char *args[], int action); + static string helpTimeLeft(int narg, char *args[], int action); + static string helpSpeed(int narg, char *args[], int action); + static string helpAdvanced(int narg, char *args[], int action); + static string helpConfiguration(int narg, char *args[], int action); + static string helpImage(int narg, char *args[], int action); + static string helpCounter(int narg, char *args[], int action); + static string helpADC(int narg, char *args[], int action); + static string helpEnablefwrite(int narg, char *args[], int action); + static string helpOverwrite(int narg, char *args[], int action); + static string helpReceiver(int narg, char *args[], int action); + static string helpPattern(int narg, char *args[], int action); + static string helpPulse(int narg, char *args[], int action); + + + + + + + + + + + + + private: + + + slsDetectorUtils *myDet; + + string cmdUnderDevelopment(int narg, char *args[], int action); + string cmdUnknown(int narg, char *args[], int action); + string cmdAcquire(int narg, char *args[], int action); + string cmdData(int narg, char *args[], int action); + string cmdFrame(int narg, char *args[], int action); + string cmdStatus(int narg, char *args[], int action); + string cmdFree(int narg, char *args[], int action); + string cmdAdd(int narg, char *args[], int action); + string cmdRemove(int narg, char *args[], int action); + string cmdHostname(int narg, char *args[], int action); + string cmdId(int narg, char *args[], int action); + string cmdMaster(int narg, char *args[], int action); + string cmdSync(int narg, char *args[], int action); + string cmdHelp(int narg, char *args[], int action); + string cmdExitServer(int narg, char *args[], int action); + string cmdSettingsDir(int narg, char *args[], int action); + string cmdCalDir(int narg, char *args[], int action); + string cmdTrimEn(int narg, char *args[], int action); + string cmdOutDir(int narg, char *args[], int action); + string cmdFileName(int narg, char *args[], int action); + string cmdFileIndex(int narg, char *args[], int action); + string cmdFlatField(int narg, char *args[], int action); + string cmdRateCorr(int narg, char *args[], int action); + string cmdBadChannels(int narg, char *args[], int action); + string cmdAngConv(int narg, char *args[], int action); + string cmdThreaded(int narg, char *args[], int action); + string cmdPositions(int narg, char *args[], int action); + string cmdScripts(int narg, char *args[], int action); + string cmdScans(int narg, char *args[], int action); + string cmdNetworkParameter(int narg, char *args[], int action); + string cmdPort(int narg, char *args[], int action); + string cmdLock(int narg, char *args[], int action); + string cmdLastClient(int narg, char *args[], int action); + string cmdOnline(int narg, char *args[], int action); + string cmdConfigureMac(int narg, char *args[], int action); + string cmdDetectorSize(int narg, char *args[], int action); + string cmdSettings(int narg, char *args[], int action); + string cmdSN(int narg, char *args[], int action); + string cmdDigiTest(int narg, char *args[], int action); + string cmdRegister(int narg, char *args[], int action); + string cmdDAC(int narg, char *args[], int action); + string cmdTiming(int narg, char *args[], int action); + string cmdTimer(int narg, char *args[], int action); + string cmdTimeLeft(int narg, char *args[], int action); + string cmdSpeed(int narg, char *args[], int action); + string cmdAdvanced(int narg, char *args[], int action); + string cmdConfiguration(int narg, char *args[], int action); + string cmdImage(int narg, char *args[], int action); + string cmdCounter(int narg, char *args[], int action); + string cmdADC(int narg, char *args[], int action); + string cmdEnablefwrite(int narg, char *args[], int action); + string cmdOverwrite(int narg, char *args[], int action); + string cmdReceiver(int narg, char *args[], int action); + string cmdPattern(int narg, char *args[], int action); + string cmdPulse(int narg, char *args[], int action); + + + int numberOfCommands; + string cmd; + + typedef string (slsDetectorCommand::*MemFuncGetter)(int narg, char *args[], int action); + + + struct FuncTable + { + string m_pFuncName; + //const char* m_pFuncName; + MemFuncGetter m_pFuncPtr; + }; + + + + FuncTable descrToFuncMap[1000]; + + + + +}; + + + +#endif + diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp new file mode 100644 index 000000000..4e554750f --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.cpp @@ -0,0 +1,324 @@ +#include "slsDetectorUsers.h" +#include "detectorData.h" +#include "multiSlsDetector.h" +#include "multiSlsDetectorCommand.h" + + +slsDetectorUsers::slsDetectorUsers(int id) : myDetector(NULL){ + + myDetector=new multiSlsDetector(id); + myCmd=new multiSlsDetectorCommand(myDetector); +}; + + +slsDetectorUsers::~slsDetectorUsers() { + if (myDetector) + delete myDetector; +}; + + + +string slsDetectorUsers::getDetectorDeveloper(){ + return myDetector->getDetectorDeveloper(); +} + + + +int slsDetectorUsers::setOnline(int const online){ + return myDetector->setOnline(online); +} + +void slsDetectorUsers::startMeasurement(){ + myDetector->acquire(0); +} + +int slsDetectorUsers::stopMeasurement(){ + return myDetector->stopAcquisition(); +} + + +int slsDetectorUsers::getDetectorStatus(){ + return (int)myDetector->getRunStatus(); +} + +string slsDetectorUsers::getFilePath(){ + return myDetector->getFilePath(); +} + + +string slsDetectorUsers::setFilePath(string s){ + return myDetector->setFilePath(s); +} + + +string slsDetectorUsers::getFileName(){ + return myDetector->getFileName(); +} + +string slsDetectorUsers::setFileName(string s){ + return myDetector->setFileName(s); +} + +int slsDetectorUsers::getFileIndex(){ + return (int)myDetector->getFileIndex(); +} + +int slsDetectorUsers::setFileIndex(int i){ + return (int)myDetector->setFileIndex(i); +} + +string slsDetectorUsers::getFlatFieldCorrectionDir(){ + return myDetector->getFlatFieldCorrectionDir(); +} + +string slsDetectorUsers::setFlatFieldCorrectionDir(string dir){ + return myDetector->setFlatFieldCorrectionDir(dir); +} + +string slsDetectorUsers::getFlatFieldCorrectionFile(){ + return myDetector->getFlatFieldCorrectionFile(); +}; + +int slsDetectorUsers::setFlatFieldCorrectionFile(string fname){ + return myDetector->setFlatFieldCorrectionFile(fname); +} + +int slsDetectorUsers::enableFlatFieldCorrection(int i){ + return myDetector->enableFlatFieldCorrection(i); +} + +int slsDetectorUsers::enableCountRateCorrection(int i){ + return myDetector->enableCountRateCorrection(i); +} + +int slsDetectorUsers::enablePixelMaskCorrection(int i){ + return myDetector->enablePixelMaskCorrection(i); +} +int slsDetectorUsers::enableAngularConversion(int i){ + return myDetector->enableAngularConversion(i); +} +int slsDetectorUsers::enableWriteToFile(int i){ + return myDetector->enableWriteToFile(i); +} + +int slsDetectorUsers::setPositions(int nPos, double *pos){ + return myDetector->setPositions(nPos, pos); +} + +int slsDetectorUsers::getPositions(double *pos){ + return myDetector->getPositions(pos); +} + +int slsDetectorUsers::setDetectorSize(int x0, int y0, int nx, int ny){ + if(myDetector->getTotalNumberOfChannels(slsDetectorDefs::Y)>1) + return 1; + int nmod=nx/(myDetector->getChansPerMod(0)); + cout << myDetector->getChansPerMod(0) << " " << nx << " " << nmod << endl; + return myDetector->setNumberOfModules(nmod)*myDetector->getChansPerMod(0);} + +int slsDetectorUsers::getDetectorSize(int &x0, int &y0, int &nx, int &ny){ + y0=0; + x0=0; + nx=myDetector->getTotalNumberOfChannels(slsDetectorDefs::X); + ny=myDetector->getTotalNumberOfChannels(slsDetectorDefs::Y); + return nx*ny; +} + +int slsDetectorUsers::getMaximumDetectorSize(int &nx, int &ny){ + nx=myDetector->getMaxNumberOfChannelsPerDetector(slsDetectorDefs::X); + ny=myDetector->getMaxNumberOfChannelsPerDetector(slsDetectorDefs::Y); + return nx*ny; +} + +int slsDetectorUsers::setBitDepth(int i){ + return myDetector->setDynamicRange(i); +} + + +int slsDetectorUsers::setSettings(int isettings){ + return myDetector->slsDetectorBase::setSettings(isettings); +} + +int slsDetectorUsers::getThresholdEnergy(){ + return myDetector->getThresholdEnergy(-1); +} + +int slsDetectorUsers::setThresholdEnergy(int e_eV){ + return myDetector->setThresholdEnergy(e_eV); +} + +int slsDetectorUsers::getBeamEnergy(){ + return 2*myDetector->getThresholdEnergy(); +} + +int slsDetectorUsers::setBeamEnergy(int e_eV){ + return 2*myDetector->setThresholdEnergy(e_eV/2); +} + +double slsDetectorUsers::setExposureTime(double t, bool inseconds){ + int64_t tms = (int64_t)(t * (1E+9)); + if (t < 0) tms = -1; + if(!inseconds) + return myDetector->setExposureTime((int64_t)t); + else + return ((1E-9) * (double)myDetector->setExposureTime(tms)); +} + +double slsDetectorUsers::setExposurePeriod(double t, bool inseconds){ + int64_t tms = (int64_t)(t * (1E+9)); + if (t < 0) tms = -1; + if(!inseconds) + return myDetector->setExposurePeriod((int64_t)t); + else + return ((1E-9) * (double)myDetector->setExposurePeriod(tms)); +} + +double slsDetectorUsers::setDelayAfterTrigger(double t, bool inseconds){ + int64_t tms = (int64_t)(t * (1E+9)); + if (t < 0) tms = -1; + if(!inseconds) + return myDetector->setDelayAfterTrigger((int64_t)t); + else + return ((1E-9) * (double)myDetector->setDelayAfterTrigger(tms)); +} + + + +int64_t slsDetectorUsers::setNumberOfGates(int64_t t){ + return myDetector->setNumberOfGates(t); +} + +int64_t slsDetectorUsers::setNumberOfFrames(int64_t t){ + return myDetector->setNumberOfFrames(t); +} + +int64_t slsDetectorUsers::setNumberOfCycles(int64_t t){ + return myDetector->setNumberOfCycles(t); +} + +int slsDetectorUsers::setTimingMode(int pol){ + return myDetector->setTimingMode(pol); +} + +int slsDetectorUsers::readConfigurationFile(string const fname){ + return myDetector->readConfigurationFile(fname); +} + +int slsDetectorUsers::dumpDetectorSetup(string const fname){ + return myDetector->dumpDetectorSetup(fname); +} + +int slsDetectorUsers::retrieveDetectorSetup(string const fname){ + return myDetector->retrieveDetectorSetup(fname); +} + +string slsDetectorUsers::getDetectorType(){ + return myDetector->sgetDetectorsType(); +} + + + +void slsDetectorUsers::initDataset(int refresh){ + myDetector->initDataset(refresh); +} + + + + +void slsDetectorUsers::addFrame(double *data, double pos, double i0, double t, string fname, double var){ + myDetector->addFrame(data,pos,i0,t,fname,var); +} + + +void slsDetectorUsers::finalizeDataset(double *a, double *v, double *e, int &np){ + myDetector->finalizeDataset(a, v, e, np); +} + + + +int slsDetectorUsers::setReceiverMode(int n){ + return myDetector->setReadReceiverFrequency(1,n); +} + + + + +int64_t slsDetectorUsers::getModuleFirmwareVersion(){ + return myDetector->getModuleFirmwareVersion(); +} + +int64_t slsDetectorUsers::getModuleSerialNumber(int imod){ + return myDetector->getModuleSerialNumber(imod); +} + +int64_t slsDetectorUsers::getDetectorFirmwareVersion(){ + return myDetector->getDetectorFirmwareVersion(); +} + +int64_t slsDetectorUsers::getDetectorSerialNumber(){ + return myDetector->getDetectorSerialNumber(); +} + +int64_t slsDetectorUsers::getDetectorSoftwareVersion(){ + return myDetector->getDetectorSoftwareVersion(); +} + +int64_t slsDetectorUsers::getThisSoftwareVersion(){ + return myDetector->getThisSoftwareVersion(); +} + + + + +void slsDetectorUsers::registerDataCallback(int( *userCallback)(detectorData*, int, int, void*), void *pArg){ + myDetector->registerDataCallback(userCallback,pArg); +} + +void slsDetectorUsers::registerRawDataCallback(int( *userCallback)(double*, int, void*), void *pArg){ + myDetector->registerRawDataCallback(userCallback,pArg); +} + +void slsDetectorUsers::registerAcquisitionFinishedCallback(int( *func)(double,int, void*), void *pArg){ + myDetector->registerAcquisitionFinishedCallback(func,pArg); +} + +void slsDetectorUsers::registerGetPositionCallback( double (*func)(void*),void *arg){ + myDetector->registerGetPositionCallback(func,arg); +} + +void slsDetectorUsers::registerConnectChannelsCallback( int (*func)(void*),void *arg){ + myDetector->registerConnectChannelsCallback(func,arg); +} + +void slsDetectorUsers::registerDisconnectChannelsCallback( int (*func)(void*),void *arg){ + myDetector->registerDisconnectChannelsCallback(func,arg); +} + +void slsDetectorUsers::registerGoToPositionCallback( int (*func)(double,void*),void *arg){ + myDetector->registerGoToPositionCallback(func,arg); +} + +void slsDetectorUsers::registerGoToPositionNoWaitCallback( int (*func)(double,void*),void *arg){ + myDetector->registerGoToPositionNoWaitCallback(func,arg); +} + +void slsDetectorUsers::registerGetI0Callback( double (*func)(int,void*),void *arg){ + myDetector->registerGetI0Callback(func,arg); +} + + +string slsDetectorUsers::putCommand(int narg, char *args[], int pos){ + if(narg < 2) + return string("Error: Insufficient Parameters"); + return myCmd->putCommand(narg, args, pos); +} + + +string slsDetectorUsers::getCommand(int narg, char *args[], int pos){ + if(narg < 1) + return string("Error: Insufficient Parameters"); + return myCmd->getCommand(narg, args, pos); +} + + + diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUsers.h b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h new file mode 100644 index 000000000..24abc2fc4 --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetectorUsers.h @@ -0,0 +1,638 @@ +#ifndef SLS_DETECTOR_USERS_H +#define SLS_DETECTOR_USERS_H + + + +/** + * + * + * + * @author Anna Bergamaschi + * @version 0.1alpha + */ + + + +class detectorData; +class multiSlsDetector; +class multiSlsDetectorCommand; + + +#include +#include + + +using namespace std; + + + +/* + \mainpage +

API for SLS detectors data acquisition

+
+*/ +/** + \mainpage + + +

API for SLS detectors data acquisition

+ +
+ + Although the SLS detectors group delvelops several types of detectors (1/2D, counting/integrating etc.) it is common interest of the group to use a common platfor for data acquisition + + The architecture of the acquisitions system is intended as follows: + \li A socket server running on the detector (or more than one in some special cases) + \li C++ classes common to all detectors for client-server communication. These can be supplied to users as libraries and embedded also in acquisition systems which are not developed by the SLS + \li the possibility of using a Qt-based graphical user interface (with eventually root analisys capabilities) + \li the possibility of running all commands from command line. In order to ensure a fast operation of this so called "text client" the detector parameters should not be re-initialized everytime. For this reason a shared memory block is allocated where the main detector flags and parameters are stored + \li a Root library for data postprocessing and detector calibration (energy, angle). + + +slsDetectorUsers is a class to control the detector which should be instantiated by the users in their acquisition software (EPICS, spec etc.). A callback for dislaying the data can be registered. +More advanced configuration functions are not implemented and can be written in a configuration file tha can be read/written. + +slsReceiverUsers is a class to receive the data for detectors with external data receiver (e.g. GOTTHARD). Callbacks can be registered to process the data or save them in specific formats. + +detectorData is a structure containing the data and additional information which is used to return the data e.g. to the GUI for displaying them. + + +You can find examples of how this classes can be instatiated in mainClient.cpp and mainReceiver.cpp + + + \authors Anna Bergamaschi, Dhanya Maliakal + @version 0.2 +

Currently supported detectors

+\li MYTHEN +\li GOTTHARD controls +\li GOTTHARD data receiver +

Coming soon

+\li EIGER + + +*/ +/** + +@libdoc The slsDetectorUsers class is a minimal interface class which should be instantiated by the users in their acquisition software (EPICS, spec etc.). More advanced configuration functions are not implemented and can be written in a configuration or parameters file that can be read/written. +*/ +/** + @short Class for detector functionalitiesto embed the detector controls in the users custom interface e.g. EPICS, Lima etc. + +*/ + + +class slsDetectorUsers + { + + public: + + /** @short default constructor */ + slsDetectorUsers(int id=0); + + + /** @short virtual destructor */ + virtual ~slsDetectorUsers(); + + + + /** + @short useful to define subset of working functions + \returns "PSI" or "Dectris" + */ + string getDetectorDeveloper(); + + + + /** @short sets the onlineFlag + \param online can be: -1 returns wether the detector is in online (1) or offline (0) state; 0 detector in offline state; 1 detector in online state + \returns 0 (offline) or 1 (online) + */ + int setOnline(int const online=-1); + + /** + @short start measurement and acquires + \returns OK/FAIL + */ + void startMeasurement(); + + /** + @short stop measurement + \returns OK/FAIL + */ + int stopMeasurement(); + + /** + @short get run status + \returns status mask + */ + int getDetectorStatus(); + + /** + @short returns the default output files path + */ + string getFilePath(); + + /** + @short sets the default output files path + \param s file path + \returns file path + */ + string setFilePath(string s); + + /** + @short + \returns the default output files root name + */ + string getFileName(); + + /** + @short sets the default output files path + \param s file name + \returns the default output files root name + + */ + string setFileName(string s); + + /** + @short + \returns the default output file index + */ + int getFileIndex(); + + /** + @short sets the default output file index + \param i file index + \returns the default output file index + */ + int setFileIndex(int i); + + /** + @short get flat field corrections file directory + \returns flat field correction file directory + */ + string getFlatFieldCorrectionDir(); + + /** + @short set flat field corrections file directory + \param dir flat field correction file directory + \returns flat field correction file directory + */ + string setFlatFieldCorrectionDir(string dir); + + /** + @short get flat field corrections file name + \returns flat field correction file name + */ + string getFlatFieldCorrectionFile(); + + /** + @short set flat field correction file + \param fname name of the flat field file (or "" if disable) + \returns 0 if disable (or file could not be read), >0 otherwise + */ + int setFlatFieldCorrectionFile(string fname=""); + + + + /** + @short enable/disable flat field corrections (without changing file name) + \param i 0 disables, 1 enables, -1 gets + \returns 0 if ff corrections disabled, 1 if enabled + */ + int enableFlatFieldCorrection(int i=-1); + + /** + @short enable/disable count rate corrections + \param i 0 disables, 1 enable, -1 gets + \returns 0 if count corrections disabled, 1 if enabled + */ + int enableCountRateCorrection(int i=-1); + + /** + @short enable/disable bad channel corrections + \param i 0 disables, 1 enables, -1 gets + \returns 0 if bad channels corrections disabled, 1 if enabled + */ + int enablePixelMaskCorrection(int i=-1); + + /** + @short enable/disable angular conversion + \param i 0 disables, 1 enables, -1 gets + \returns 0 if angular conversion disabled, 1 if enabled + */ + int enableAngularConversion(int i=-1); + + /**Enable write file function included*/ + + int enableWriteToFile(int i=-1); + + /** + @short set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ + int setPositions(int nPos, double *pos); + + /** + @short get positions for the acquisition + \param pos array which will contain the encoder positions + \returns number of positions + */ + int getPositions(double *pos=NULL); + + /** + @short sets the detector size + \param x0 horizontal position origin in channel number (-1 unchanged) + \param y0 vertical position origin in channel number (-1 unchanged) + \param nx number of channels in horiziontal (-1 unchanged) + \param ny number of channels in vertical (-1 unchanged) + \returns OK/FAIL + */ + int setDetectorSize(int x0=-1, int y0=-1, int nx=-1, int ny=-1); + + + /** + @short gets detector size + \param x0 horizontal position origin in channel number + \param y0 vertical position origin in channel number + \param nx number of channels in horiziontal + \param ny number of channels in vertical + \returns OK/FAIL + */ + int getDetectorSize(int &x0, int &y0, int &nx, int &ny); + /** + @short setsthe maximum detector size + \param x0 horizontal position origin in channel number + \param y0 vertical position origin in channel number + \param nx number of channels in horiziontal + \param ny number of channels in vertical + \returns OK/FAIL + */ + int getMaximumDetectorSize(int &nx, int &ny); + + + /** + @short set/get dynamic range + \param i dynamic range (-1 get) + \returns current dynamic range + */ + int setBitDepth(int i=-1); + + + + /** + @short set detector settings + \param isettings settings index (-1 gets) + \returns current settings + */ + int setSettings(int isettings=-1); + + /** + @short get threshold energy + \returns current threshold value for imod in ev (-1 failed) + */ + int getThresholdEnergy(); + + + /** + @short set threshold energy + \param e_eV threshold in eV + \returns current threshold value for imod in ev (-1 failed) + */ + int setThresholdEnergy(int e_eV); + + /** + @short get beam energy -- only for dectris! + \returns current beam energy + */ + int getBeamEnergy(); + + + /** + @short set beam energy -- only for dectris! + \param e_eV beam in eV + \returns current beam energyin ev (-1 failed) + */ + int setBeamEnergy(int e_eV); + + /** + @short set/get exposure time value + \param t time in sn (-1 gets) + \param inseconds true if the value is in s, else ns + \returns timer set value in ns, or s if specified + */ + + double setExposureTime(double t=-1, bool inseconds=false); + + /** + @short set/get exposure period + \param t time in ns (-1 gets) + \param inseconds true if the value is in s, else ns + \returns timer set value in ns, or s if specified + */ + double setExposurePeriod(double t=-1, bool inseconds=false); + + /** + @short set/get delay after trigger + \param t time in ns (-1 gets) + \param inseconds true if the value is in s, else ns + \returns timer set value in ns, or s if specified + */ + double setDelayAfterTrigger(double t=-1, bool inseconds=false); + + /** + @short set/get number of gates + \param t number of gates (-1 gets) + \returns number of gates + */ + int64_t setNumberOfGates(int64_t t=-1); + + /** + @short set/get number of frames i.e. number of exposure per trigger + \param t number of frames (-1 gets) + \returns number of frames + */ + int64_t setNumberOfFrames(int64_t t=-1); + + /** + @short set/get number of cycles i.e. number of triggers + \param t number of frames (-1 gets) + \returns number of frames + */ + int64_t setNumberOfCycles(int64_t t=-1); + + + /** + @short set/get the external communication mode + \param pol value to be set \sa getTimingMode + \returns current external communication mode + */ + int setTimingMode(int pol=-1); + + /** + @short Reads the configuration file -- will contain all the informations needed for the configuration (e.g. for a PSI detector caldir, settingsdir, angconv, badchannels, hostname etc.) + \param fname file name + \returns OK or FAIL + */ + int readConfigurationFile(string const fname); + + + /** + @short Reads the parameters from the detector and writes them to file + \param fname file to write to + \returns OK or FAIL + + */ + int dumpDetectorSetup(string const fname); + /** + @short Loads the detector setup from file + \param fname file to read from + \returns OK or FAIL + + */ + int retrieveDetectorSetup(string const fname); + + /** + @short useful for data plotting etc. + \returns Mythen, Eiger, Gotthard etc. + */ + string getDetectorType(); + + /** + @short sets the mode by which gui requests data from receiver + \param n is 0 for random requests for fast acquisitions and greater than 0 for nth read requests + \returns the mode set in the receiver + */ + int setReceiverMode(int n=-1); + + /** + @short register calbback for accessing detector final data + \param userCallback function for plotting/analyzing the data. Its arguments are the data structure d and the frame number f, s is for subframe number for eiger for 32 bit mode + */ + + void registerDataCallback(int( *userCallback)(detectorData* d, int f, int s, void*), void *pArg); + + /** + @short register callback for accessing raw data - if the rawDataCallback is registered, no filewriting/postprocessing will be carried on automatically by the software - the raw data are deleted by the software + \param userCallback function for postprocessing and saving the data - p is the pointer to the data, n is the number of channels + */ + + void registerRawDataCallback(int( *userCallback)(double* p, int n, void*), void *pArg); + + /** + @short function to initalize a set of measurements (reset binning if angular conversion, reset summing otherwise) - can be overcome by the user's functions thanks to the virtual property + \param refresh if 1, all parameters like ffcoefficients, badchannels, ratecorrections etc. are reset (should be called at least onece with this option), if 0 simply reset merging/ summation + */ + + virtual void initDataset(int refresh); + + + /** + @short adds frame to merging/summation - can be overcome by the user's functions thanks to the virtual property + \param data pointer to the raw data + \param pos encoder position + \param i0 beam monitor readout for intensity normalization (if 0 not performed) + \param t exposure time in seconds, required only if rate corrections + \param fname file name (unused since filewriting would be performed by the user) + \param var optional parameter - unused. + */ + + virtual void addFrame(double *data, double pos, double i0, double t, string fname, double var); + + /** + @short finalizes the data set returning the array of angles, values and errors to be used as final data - can be overcome by the user's functions thanks to the virtual property + \param a pointer to the array of angles - can be null if no angular coversion is required + \param v pointer to the array of values + \param e pointer to the array of errors + \param np reference returning the number of points + */ + + virtual void finalizeDataset(double *a, double *v, double *e, int &np); + + /** + get get Module Firmware Version + \returns id + */ + int64_t getModuleFirmwareVersion(); + + /** + get get Module Serial Number + @param imod module number + \returns id + */ + int64_t getModuleSerialNumber(int imod=-1); + + /** + get get Detector Firmware Version + \returns id + */ + int64_t getDetectorFirmwareVersion(); + + /** + get get Detector Serial Number + \returns id + */ + int64_t getDetectorSerialNumber(); + + /** + get get Detector Software Version + \returns id + */ + int64_t getDetectorSoftwareVersion(); + + /** + get this Software Version + \returns id + */ + int64_t getThisSoftwareVersion(); + + /** + @short register calbback for accessing detector final data + \param func function to be called at the end of the acquisition. gets detector status and progress index as arguments + */ + + void registerAcquisitionFinishedCallback(int( *func)(double,int, void*), void *pArg); + + /** + @short register calbback for reading detector position + \param func function for reading the detector position + */ + + void registerGetPositionCallback( double (*func)(void*),void *arg); + /** + @short register callback for connecting to the epics channels + \param func function for connecting to the epics channels + */ + void registerConnectChannelsCallback( int (*func)(void*),void *arg); + /** + @short register callback to disconnect the epics channels + \param func function to disconnect the epics channels + */ + void registerDisconnectChannelsCallback( int (*func)(void*),void *arg); + /** + @short register callback for moving the detector + \param func function for moving the detector + */ + void registerGoToPositionCallback( int (*func)(double,void*),void *arg); + /** + @short register callback for moving the detector without waiting + \param func function for moving the detector + */ + void registerGoToPositionNoWaitCallback( int (*func)(double,void*),void *arg); + /** + @short register calbback reading to I0 + \param func function for reading the I0 (called with parameter 0 before the acquisition, 1 after and the return value used as I0) + */ + void registerGetI0Callback( double (*func)(int,void*),void *arg); + + /** + @short sets parameters in command interface http://www.psi.ch/detectors/UsersSupportEN/slsDetectorClientHowTo.pdf + \param narg value to be set + \param args value to be set + \param pos position of detector in multislsdetector list + \returns answer string + */ + string putCommand(int narg, char *args[], int pos=-1); + + /** + @short gets parameters in command interface http://www.psi.ch/detectors/UsersSupportEN/slsDetectorClientHowTo.pdf + \param narg value to be set + \param args value to be set + \param pos position of detector in multislsdetector list + \returns answer string + */ + string getCommand(int narg, char *args[], int pos=-1); + + /************************************************************************ + + STATIC FUNCTIONS + + *********************************************************************/ + + /** @short returns string from run status index + \param s run status index + \returns string error, waiting, running, data, finished or unknown when wrong index + */ + static string runStatusType(int s){ \ + switch (s) { \ + case 0: return string("idle"); \ + case 1: return string("error"); \ + case 2: return string("waiting"); \ + case 3: return string("finished"); \ + case 4: return string("data"); \ + case 5: return string("running"); \ + default: return string("unknown"); \ + }}; + + + + /** @short returns detector settings string from index + \param s can be standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain + \returns setting index (-1 unknown string) + */ + + static int getDetectorSettings(string s){ \ + if (s=="standard") return 0; \ + if (s=="fast") return 1; \ + if (s=="highgain") return 2; \ + if (s=="dynamicgain") return 3; \ + if (s=="lowgain") return 4; \ + if (s=="mediumgain") return 5; \ + if (s=="veryhighgain") return 6; \ + return -1; }; + + /** @short returns detector settings string from index + \param s settings index + \returns standard, fast, highgain, dynamicgain, lowgain, mediumgain, veryhighgain, undefined when wrong index + */ + static string getDetectorSettings(int s){\ + switch(s) { \ + case 0: return string("standard");\ + case 1: return string("fast");\ + case 2: return string("highgain");\ + case 3: return string("dynamicgain"); \ + case 4: return string("lowgain"); \ + case 5: return string("mediumgain"); \ + case 6: return string("veryhighgain"); \ + default: return string("undefined"); \ + }}; + + + + /** + @short returns external communication mode string from index + \param f index for communication mode + \returns auto, trigger, ro_trigger, gating, triggered_gating, unknown when wrong mode + */ + + static string getTimingMode(int f){ \ + switch(f) { \ + case 0: return string( "auto"); \ + case 1: return string("trigger"); \ + case 2: return string("ro_trigger"); \ + case 3: return string("gating"); \ + case 4: return string("triggered_gating"); \ + default: return string( "unknown"); \ + } }; + + /** + @short returns external communication mode string from index + \param f index for communication mode + \returns auto, trigger, ro_trigger, gating, triggered_gating, unknown when wrong mode + */ + + static int getTimingMode(string s){ \ + if (s== "auto") return 0; \ + if (s== "trigger") return 1; \ + if (s== "ro_trigger") return 2; \ + if (s== "gating") return 3; \ + if (s== "triggered_gating") return 4; \ + return -1; }; + + private: + multiSlsDetector *myDetector; + multiSlsDetectorCommand *myCmd; + }; + +#endif diff --git a/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp b/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp new file mode 100644 index 000000000..495eaf210 --- /dev/null +++ b/slsDetectorSoftware/slsDetector/slsDetectorUtils.cpp @@ -0,0 +1,1036 @@ +#include "slsDetectorUtils.h" +#include "usersFunctions.h" +#include "slsDetectorCommand.h" +#include "postProcessing.h" +#include "enCalLogClass.h" +#include "angCalLogClass.h" + +#include +#include +#include + +using namespace std; +slsDetectorUtils::slsDetectorUtils() { + + +#ifdef VERBOSE + cout << "setting callbacks" << endl; +#endif + acquisition_finished=NULL; + acqFinished_p=NULL; + measurement_finished=NULL; + measFinished_p=NULL; + progress_call=0; + pProgressCallArg=0; + registerGetPositionCallback(&defaultGetPosition, NULL); + registerConnectChannelsCallback(&defaultConnectChannels,NULL); + registerDisconnectChannelsCallback(&defaultDisconnectChannels,NULL); + registerGoToPositionCallback(&defaultGoToPosition,NULL); + registerGoToPositionNoWaitCallback(&defaultGoToPositionNoWait,NULL); + registerGetI0Callback(&defaultGetI0,NULL); +#ifdef VERBOSE + + registerAcquisitionFinishedCallback(&dummyAcquisitionFinished,this); + registerMeasurementFinishedCallback(&dummyMeasurementFinished,this); + cout << "done " << endl; +#endif + +}; + + + + + +int slsDetectorUtils::acquire(int delflag){ + + //ensure acquire isnt started multiple times by same client + if(getAcquiringFlag() == false) + setAcquiringFlag(true); + else{ + std::cout << "Error: Acquire has already been started." << std::endl; + return FAIL; + } + + + bool receiver = (setReceiverOnline()==ONLINE_FLAG); + if(!receiver){ + setDetectorIndex(-1); + }else{ + //put receiver read frequency to random if no gui + int ret = setReadReceiverFrequency(0); + if(ret>0 && (acquisition_finished == NULL)){ + std::cout << "Error: receiver read frequency is set to " << ret << " but should be > 0 only when using gui." << std::endl; + ret = setReadReceiverFrequency(1,0); + std::cout << "Current receiver read frequency: " << ret << std::endl; + } + } + + int nc=setTimer(CYCLES_NUMBER,-1); + int nf=setTimer(FRAME_NUMBER,-1); + if (nc==0) nc=1; + if (nf==0) nf=1; + + int multiframe = nc*nf; + + pthread_mutex_lock(&mg); + acquiringDone = 0; + pthread_mutex_unlock(&mg); + + // setTotalProgress(); + //moved these 2 here for measurement change + progressIndex=0; + *stoppedFlag=0; + + angCalLogClass *aclog=NULL; + enCalLogClass *eclog=NULL; + // int lastindex=startindex, nowindex=startindex; + int connectChannels=0; + +#ifdef VERBOSE + cout << "Acquire function "<< delflag << endl; + cout << "Stopped flag is "<< stoppedFlag << delflag << endl; +#endif + + void *status; + + + if ((*correctionMask&(1<< ANGULAR_CONVERSION)) || (*correctionMask&(1<< I0_NORMALIZATION)) || getActionMode(angCalLog) || (getScanMode(0)==positionScan)|| (getScanMode(1)==positionScan)) { + if (connectChannels==0) + if (connect_channels) { + connect_channels(CCarg); + connectChannels=1; + } + } + + + if (getActionMode(angCalLog)) { + aclog=new angCalLogClass(this); + } + if (getActionMode(enCalLog)) { + eclog=new enCalLogClass(this); + + } + + + + setJoinThread(0); + positionFinished(0); + + + + + int nm=timerValue[MEASUREMENTS_NUMBER]; + if (nm<1) + nm=1; + + + int np=getNumberOfPositions(); + if (np<1) + np=1; + + + int ns0=1; + if (*actionMask & (1 << MAX_ACTIONS)) { + ns0=getScanSteps(0); + if (ns0<1) + ns0=1; + } + + int ns1=1; + if (*actionMask & (1 << (MAX_ACTIONS+1))) { + ns1=getScanSteps(1); + if (ns1<1) + ns1=1; + } + + if(receiver){ + if(getReceiverStatus()!=IDLE) + stopReceiver(); + if(setReceiverOnline()==OFFLINE_FLAG) + *stoppedFlag=1; + + //multi detectors shouldnt have different receiver read frequencies enabled/disabled + if(setReadReceiverFrequency(0) < 0){ + std::cout << "Error: The receiver read frequency is invalid:" << setReadReceiverFrequency(0) << std::endl; + *stoppedFlag=1; + } + + if(setReceiverOnline()==OFFLINE_FLAG) + *stoppedFlag=1; + } + + + + if (*threadedProcessing) { + sem_init(&sem_queue,0,0); + startThread(delflag); + } +#ifdef VERBOSE + cout << " starting thread " << endl; +#endif + + //resets frames caught in receiver + if(receiver){ + pthread_mutex_lock(&mg); + resetFramesCaught(); + pthread_mutex_unlock(&mg); + } + + for(int im=0;im0) { + moveDetector(detPositions[ip]); + IncrementPositionIndex(); +#ifdef VERBOSE + std::cout<< "moving to position" << std::endl; +#endif + } + } else + break; + + + pthread_mutex_lock(&mp); + createFileName(); + pthread_mutex_unlock(&mp); + + if (*stoppedFlag==0) { + executeAction(scriptBefore); + } else + break; + + + + + if (*stoppedFlag==0) { + + + executeAction(headerBefore); + + if (*correctionMask&(1<< ANGULAR_CONVERSION) || aclog){// || eclog) { + positionFinished(0); + setCurrentPosition(getDetectorPosition()); + } + + + if (aclog) + aclog->addStep(getCurrentPosition(), getCurrentFileName()); + + if (eclog) + eclog->addStep(setDAC(-1,THRESHOLD,0), getCurrentFileName()); + + + if (*correctionMask&(1<< I0_NORMALIZATION)) { + if (get_i0) + get_i0(0, IOarg); + } + + setCurrentFrameIndex(0); + + if(receiver) + pthread_mutex_lock(&mg); + if (multiframe>1) + setFrameIndex(0); + else + setFrameIndex(-1); + + + if(receiver){ + pthread_mutex_unlock(&mg);//unlock previous + pthread_mutex_lock(&mp); + createFileName(); + pthread_mutex_unlock(&mp); + //send receiver file name + pthread_mutex_lock(&mg); + setFileName(fileIO::getFileName()); + if(setReceiverOnline()==OFFLINE_FLAG){ + stopReceiver(); + *stoppedFlag=1; + pthread_mutex_unlock(&mg); + break; + } + //start receiver + if(startReceiver() == FAIL) { + stopReceiver(); + *stoppedFlag=1; + pthread_mutex_unlock(&mg); + break; + } + pthread_mutex_unlock(&mg); + } +#ifdef VERBOSE + cout << "Acquiring " << endl; +#endif + startAndReadAll(); +#ifdef VERBOSE + cout << "finished " << endl; + cout << "returned! " << endl; +#endif + + + + if (*correctionMask&(1<< I0_NORMALIZATION)) { + if (get_i0) + currentI0=get_i0(1,IOarg); // this is the correct i0!!!!! + } +#ifdef VERBOSE + cout << "pos finished? " << endl; +#endif + + positionFinished(1); + +#ifdef VERBOSE + cout << "done! " << endl; +#endif + + + if (*threadedProcessing==0){ +#ifdef VERBOSE + cout << "start unthreaded process data " << endl; +#endif + + processData(delflag); + } + + } else + break; + + + //offline + pthread_mutex_lock(&mg); + if(setReceiverOnline()==OFFLINE_FLAG){ + // wait until data processing thread has finished the data + acquiringDone = 1; + pthread_mutex_unlock(&mg); + if (*threadedProcessing) { + sem_wait(&sem_queue); + pthread_mutex_lock(&mg); + acquiringDone = 0; + pthread_mutex_unlock(&mg); + } + +#ifdef VERBOSE + cout << "check data queue size " << endl; +#endif + /*while (dataQueueSize()){ + //#ifdef VERBOSE + cout << "AAAAAAAAA check data queue size " << endl; + //#endif + usleep(100000); + }*/ + + if ((getDetectorsType()==GOTTHARD) || (getDetectorsType()==MOENCH) || (getDetectorsType()==JUNGFRAU) ){ + if((*correctionMask)&(1<0) + nc=timerValue[CYCLES_NUMBER]; + + if (timerValue[MEASUREMENTS_NUMBER]>0) + nm=timerValue[MEASUREMENTS_NUMBER]; + + if (*numberOfPositions>0) + npos=*numberOfPositions; + + if ((nScanSteps[0]>0) && (*actionMask & (1 << MAX_ACTIONS))) + nscan[0]=nScanSteps[0]; + + if ((nScanSteps[1]>0) && (*actionMask & (1 << (MAX_ACTIONS+1)))) + nscan[1]=nScanSteps[1]; + + totalProgress=nm*nf*nc*npos*nscan[0]*nscan[1]; + +#ifdef VERBOSE + cout << "nc " << nc << endl; + cout << "nm " << nm << endl; + cout << "nf " << nf << endl; + cout << "npos " << npos << endl; + cout << "nscan[0] " << nscan[0] << endl; + cout << "nscan[1] " << nscan[1] << endl; + + cout << "Set total progress " << totalProgress << endl; +#endif + return totalProgress; +} + + + + + + + + + +int slsDetectorUtils::setBadChannelCorrection(string fname, int &nbadtot, int *badchanlist, int off){ + + int nbad; + int badlist[MAX_BADCHANS]; + + ifstream infile; + string str; + //int interrupt=0; + //int ich; + //int chmin,chmax; +#ifdef VERBOSE + std::cout << "utils: Setting bad channel correction to " << fname << std::endl; +#endif + // int modmi=0; + int modma=1; + int singlefile=0; + + string fn; + int offset=off; + + + nbadtot=0; + + if (fname=="" || fname=="none") { + ; + } else { + + if (fname.find(".sn")==string::npos && fname.find(".chans")==string::npos) { + modma=setNumberOfModules(); + singlefile=1; + } + + for (int im=0; im0 && nbadtot> sargname; + // if (ssstr.good()) { + strcpy(myargs[iargval],sargname.c_str()); + args[iargval]=myargs[iargval]; +#ifdef VERBOSE + std::cout<< args[iargval] << std::endl; +#endif + iargval++; + // } + skip=0; + } + + if (level!=2) { + if (string(args[0])==string("flatfield")) + skip=1; + else if (string(args[0])==string("badchannels")) + skip=1; + else if (string(args[0])==string("trimbits")) + skip=1; + } + if (skip==0) + cmd->executeLine(iargval,args,PUT_ACTION); + } + iline++; + } + delete cmd; + infile.close(); + + } else { + std::cout<< "Error opening " << fname << " for reading" << std::endl; + return FAIL; + } +#ifdef VERBOSE + std::cout<< "Read " << iline << " lines" << std::endl; +#endif + + if (getErrorMask()) + return FAIL; + + return OK; + + +} + + +int slsDetectorUtils::dumpDetectorSetup(string const fname, int level){ + + slsDetectorCommand *cmd; + string names[100]; + int nvar=0; + int nvar1=0; + + names[nvar++]="fname"; + names[nvar++]="index"; + names[nvar++]="dr"; + names[nvar++]="settings"; + names[nvar++]="exptime"; + names[nvar++]="period"; + names[nvar++]="frames"; + names[nvar++]="cycles"; + names[nvar++]="measurements"; + names[nvar++]="timing"; + + switch (getDetectorsType()) { + case EIGER: + names[nvar++]="flags"; + names[nvar++]="threshold"; + names[nvar++]="ratecorr"; + break; + case GOTTHARD: + case PROPIX: + case JUNGFRAU: + names[nvar++]="flags"; + names[nvar++]="delay"; + names[nvar++]="gates"; + names[nvar++]="ratecorr"; + break; + case MYTHEN: + names[nvar++]="flags"; + names[nvar++]="threshold"; + names[nvar++]="delay"; + names[nvar++]="gates"; + names[nvar++]="probes"; + names[nvar++]="fineoff"; + names[nvar++]="ratecorr"; + names[nvar++]="trimbits"; + break; + case JUNGFRAUCTB: + + names[nvar++]="dac:0"; + names[nvar++]="dac:1"; + names[nvar++]="dac:2"; + names[nvar++]="dac:3"; + names[nvar++]="dac:4"; + names[nvar++]="dac:5"; + names[nvar++]="dac:6"; + names[nvar++]="dac:7"; + names[nvar++]="dac:8"; + names[nvar++]="dac:9"; + names[nvar++]="dac:10"; + names[nvar++]="dac:11"; + names[nvar++]="dac:12"; + names[nvar++]="dac:13"; + names[nvar++]="dac:14"; + names[nvar++]="dac:15"; + names[nvar++]="adcvpp"; + + + + names[nvar++]="adcclk"; + names[nvar++]="clkdivider"; + names[nvar++]="adcphase"; + names[nvar++]="adcpipeline"; + names[nvar++]="adcinvert"; // + names[nvar++]="adcdisable"; + names[nvar++]="patioctrl"; + names[nvar++]="patclkctrl"; + names[nvar++]="patlimits"; + names[nvar++]="patloop0"; + names[nvar++]="patnloop0"; + names[nvar++]="patwait0"; + names[nvar++]="patwaittime0"; + names[nvar++]="patloop1"; + names[nvar++]="patnloop1"; + names[nvar++]="patwait1"; + names[nvar++]="patwaittime1"; + names[nvar++]="patloop2"; + names[nvar++]="patnloop2"; + names[nvar++]="patwait2"; + names[nvar++]="patwaittime2"; + } + + + + names[nvar++]="startscript"; + names[nvar++]="startscriptpar"; + names[nvar++]="stopscript"; + names[nvar++]="stopscriptpar"; + names[nvar++]="scriptbefore"; + names[nvar++]="scriptbeforepar"; + names[nvar++]="scriptafter"; + names[nvar++]="scriptafterpar"; + names[nvar++]="scan0script"; + names[nvar++]="scan0par"; + names[nvar++]="scan0prec"; + names[nvar++]="scan0steps"; + names[nvar++]="scan1script"; + names[nvar++]="scan1par"; + names[nvar++]="scan1prec"; + names[nvar++]="scan1steps"; + + switch (getDetectorsType()) { + case EIGER: + case MYTHEN: + case GOTTHARD: + case PROPIX: + case JUNGFRAU: + names[nvar++]="flatfield"; + names[nvar++]="badchannels"; + break; + + } + + switch (getDetectorsType()) { + case EIGER: + case MYTHEN: + names[nvar++]="trimbits"; + break; + + } + + // char ext[100]; + + int iv=0; + string fname1; + + + + ofstream outfile; + char *args[4]; + for (int ia=0; ia<4; ia++) { + args[ia]=new char[1000]; + } + + + + + + int nargs; + if (level==2) + nargs=2; + else + nargs=1; + + + if (level==2) { + fname1=fname+string(".config"); + writeConfigurationFile(fname1); + fname1=fname+string(".det"); + } else + fname1=fname; + + + + outfile.open(fname1.c_str(),ios_base::out); + if (outfile.is_open()) { + cmd=new slsDetectorCommand(this); + for (iv=0; ivexecuteLine(1,args,GET_ACTION) << std::endl; + } + + + strcpy(args[0],names[iv].c_str()); + if (level==2) { + fname1=fname+string(".ff"); + strcpy(args[1],fname1.c_str()); + } + outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl; + iv++; + + strcpy(args[0],names[iv].c_str()); + if (level==2) { + fname1=fname+string(".bad"); + strcpy(args[1],fname1.c_str()); + } + outfile << names[iv] << " " << cmd->executeLine(nargs,args,GET_ACTION) << std::endl; + iv++; + + + + if (level==2) { + strcpy(args[0],names[iv].c_str()); + size_t c=fname.rfind('/'); + if (cexecuteLine(nargs,args,GET_ACTION) << std::endl; + iv++; + + + } + + + delete cmd; + + outfile.close(); + } + else { + std::cout<< "Error opening parameters file " << fname1 << " for writing" << std::endl; + return FAIL; + } + +#ifdef VERBOSE + std::cout<< "wrote " < +} + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + + +//#include "slsDetectorActions_Standalone.h" +#include "slsDetectorActions.h" +#include "postProcessing.h" + +//#define MAX_TIMERS 11 +#define MAXPOS 50 + +#define DEFAULT_HOSTNAME "localhost" +#define DEFAULT_SHM_KEY 5678 +#define THIS_REVISION "$Rev: 822 $" + +//test + +/** + @short class containing all the possible detector functionalities + + (used in the PSi command line interface) +*/ + + +class slsDetectorUtils : public slsDetectorActions, public postProcessing { + + + public: + + slsDetectorUtils(); + + virtual ~slsDetectorUtils(){}; + + + virtual int getNumberOfDetectors(){return 1; }; + + + virtual int getMaxNumberOfChannelsPerDetector(dimension d){return -1;}; + + virtual int setMaxNumberOfChannelsPerDetector(dimension d,int i){return -1;}; + + //int setPositions(int nPos, double *pos){return angularConversion::setPositions(nPos, pos);}; + + // int getPositions(double *pos=NULL){return angularConversion::getPositions(pos);}; + + using slsDetectorBase::setFlatFieldCorrection; + using slsDetectorBase::getDetectorsType; + using postProcessing::setBadChannelCorrection; + + int enableFlatFieldCorrection(int i=-1) {if (i>0) setFlatFieldCorrectionFile("default"); else if (i==0) setFlatFieldCorrectionFile(""); return getFlatFieldCorrection();}; + int enablePixelMaskCorrection(int i=-1) {if (i>0) setBadChannelCorrection("default"); else if (i==0) setBadChannelCorrection(""); return getBadChannelCorrection();}; + int enableCountRateCorrection(int i=-1){if (i>0) setRateCorrection(-1); else if (i==0) setRateCorrection(0); return getRateCorrection();}; + // string getFilePath(){return fileIO::getFilePath();};; + // string setFilePath(string s){return fileIO::setFilePath(s);}; + + // string getFileName(){return fileIO::getFileName();}; + // string setFileName(string s){return fileIO::setFileName(s);}; + + // int getFileIndex(){return fileIO::getFileIndex();}; + // int setFileIndex(int s){return fileIO::setFileIndex(s);}; + + /* + int getScanPrecision(int i){return slsDetectorActions::getScanPrecision(i);}; + + int getActionMask() {return slsDetectorActions::getActionMask();}; + float getCurrentScanVariable(int i) {return slsDetectorActions::getCurrentScanVariable(i);}; + int getCurrentPositionIndex(){return angularConversion::getCurrentPositionIndex();}; + int getNumberOfPositions(){return angularConversion::getNumberOfPositions();}; + */ + + // int getActionMask() {return slsDetectorActions::getActionMask();}; + // double getCurrentScanVariable(int i) {return slsDetectorActions::getCurrentScanVariable(i);}; + // int getCurrentPositionIndex(){return angularConversion::getCurrentPositionIndex();}; + // int getNumberOfPositions(){return angularConversion::getNumberOfPositions();}; + + + // string getFlatFieldCorrectionDir(){return postProcessing::getFlatFieldCorrectionDir();}; + // string setFlatFieldCorrectionDir(string s){return postProcessing::setFlatFieldCorrectionDir(s);}; + // string getFlatFieldCorrectionFile(){return postProcessing::getFlatFieldCorrectionFile();}; + // int enableBadChannelCorrection(int i){return postProcessing::enableBadChannelCorrection(i);}; + // int enableAngularConversion(int i){return postProcessing::enableAngularConversion(i);}; + + + /** returns the detector hostname + \param pos position in the multi detector structure (is -1 returns concatenated hostnames divided by a +) + \returns hostname + */ + virtual string getHostname(int pos=-1)=0; + + + /** sets the detector hostname + \param name hostname + \param pos position in the multi detector structure (is -1 expects concatenated hostnames divided by a +) + \returns hostname + */ + virtual string setHostname(const char* name, int pos=-1)=0; + + + /** returns the detector type + \param pos position in the multi detector structure (is -1 returns type of detector with id -1) + \returns type + */ + virtual string sgetDetectorsType(int pos=-1)=0; + + /** returns the detector type + \param pos position in the multi detector structure (is -1 returns type of detector with id -1) + \returns type + */ + virtual detectorType setDetectorsType(detectorType t=GET_DETECTOR_TYPE, int pos=-1)=0; + virtual string ssetDetectorsType(detectorType t=GET_DETECTOR_TYPE, int pos=-1)=0; + virtual string ssetDetectorsType(string s, int pos=-1)=0; + + + + /** Gets the detector id (shared memory id) of an slsDetector + \param i position in the multiSlsDetector structure + \return id or -1 if FAIL + */ + virtual int getDetectorId(int i=-1)=0; + + /** Sets the detector id (shared memory id) of an slsDetector in a multiSlsDetector structure + \param ival id to be set + \param i position in the multiSlsDetector structure + \return id or -1 if FAIL (e.g. in case of an slsDetector) + */ + virtual int setDetectorId(int ival, int i=-1){return -1;}; + + + + /** + gets the network parameters (implemented for gotthard) + \param i network parameter type can be RECEIVER_IP, RECEIVER_MAC, SERVER_MAC + \returns parameter + + */ + virtual char *getNetworkParameter(networkParameter i)=0; + + /** + sets the network parameters (implemented for gotthard) + \param i network parameter type can be RECEIVER_IP, RECEIVER_MAC, SERVER_MAC + \param s value to be set + \returns parameter + + */ + virtual char *setNetworkParameter(networkParameter i, string s)=0; + + /** + changes/gets the port number + \param t type port type can be CONTROL_PORT, DATA_PORT, STOP_PORT + \param i new port number (<1024 gets) + \returns actual port number + */ + virtual int setPort(portType t, int i=-1)=0; + + /** + checks if the detector(s) are online/offline + \returns hostname if offline + */ + virtual string checkOnline()=0; + + /** + Digital test of the modules + \param mode test mode + \param imod module number for chip test or module firmware test + \returns OK or error mask + */ + virtual int digitalTest(digitalTestMode mode, int imod=0)=0; + + /** + execute trimming + \param mode trim mode + \param par1 if noise, beam or fixed setting trimming it is count limit, if improve maximum number of iterations + \param par2 if noise or beam nsigma, if improve par2!=means vthreshold will be optimized, if fixed settings par2<0 trimwith median, par2>=0 trim with level + \param imod module number (-1 all) + \returns OK or FAIl (FAIL also if some channel are 0 or 63 + */ + virtual int executeTrimming(trimMode mode, int par1, int par2, int imod=-1)=0; + + + /** + returns currently the loaded trimfile/settingsfile name + */ + virtual const char *getSettingsFile()=0; + + + /** + get current timer value + \param index timer index + \returns elapsed time value in ns or number of...(e.g. frames, gates, probes) + */ + virtual int64_t getTimeLeft(timerIndex index)=0; + + + + /** sets the number of trim energies and their value \sa sharedSlsDetector + \param nen number of energies + \param en array of energies + \returns number of trim energies + + unused! + + */ + virtual int setTrimEn(int nen, int *en=NULL)=0; + + /** returns the number of trim energies and their value \sa sharedSlsDetector + \param en pointer to the array that will contain the trim energies (in ev) + \returns number of trim energies + + unused! + */ + virtual int getTrimEn(int *en=NULL)=0; + + + + /** + set/get the use of an external signal + \param pol meaning of the signal \sa externalSignalFlag + \param signalindex index of the signal + \returns current meaning of signal signalIndex + */ + virtual externalSignalFlag setExternalSignalFlags(externalSignalFlag pol=GET_EXTERNAL_SIGNAL_FLAG , int signalindex=0)=0; + + + + + /** sets/gets the value of important readout speed parameters + \param sp is the parameter to be set/get + \param value is the value to be set, if -1 get value + \returns current value for the specified parameter + \sa speedVariable + */ + virtual int setSpeed(speedVariable sp, int value=-1)=0; + + + + + + + /** + set/get readout flags + \param flag readout flag to be set + \returns current flag + */ + virtual int setReadOutFlags(readOutFlags flag=GET_READOUT_FLAGS)=0; + + + + + + int setBadChannelCorrection(string fname, int &nbadtot, int *badchanlist, int off=0); + + + + + + /** sets/gets position of the master in a multi detector structure + \param i position of the detector in the multidetector structure + \returns position of the master in a multi detector structure (-1 no master or always in slsDetector) + */ + virtual int setMaster(int i=-1){return -1;}; + + /** + Sets/gets the synchronization mode of the various detectors + \param sync syncronization mode + \returns current syncronization mode + */ + virtual synchronizationMode setSynchronization(synchronizationMode sync=GET_SYNCHRONIZATION_MODE)=0; + + + /** + returns the detector trimbit/settings directory + */ + virtual char* getSettingsDir()=0; + + /** sets the detector trimbit/settings directory */ + virtual char* setSettingsDir(string s)=0; + + /** + returns the location of the calibration files + */ + virtual char* getCalDir()=0; + + /** + sets the location of the calibration files + */ + virtual char* setCalDir(string s)=0; + + /** Frees the shared memory - should not be used except for debugging*/ + virtual int freeSharedMemory()=0; + + + /** adds the detector with ID id in postion pos + \param id of the detector to be added (should already exist!) + \param pos position where it should be added (normally at the end of the list (default to -1) + \returns the actual number of detectors or -1 if it failed (always for slsDetector) + */ + virtual int addSlsDetector(int id, int pos=-1){return -1;}; + + + /** adds the detector name in position pos + \param name of the detector to be added (should already exist in shared memory or at least be online) + \param pos position where it should be added (normally at the end of the list (default to -1) + \return the actual number of detectors or -1 if it failed (always for slsDetector) + */ + virtual int addSlsDetector(char* name, int pos=-1){return -1;}; + + + /** + removes the detector in position pos from the multidetector + \param pos position of the detector to be removed from the multidetector system (defaults to -1 i.e. last detector) + \returns the actual number of detectors or -1 if it failed (always for slsDetector) + */ + virtual int removeSlsDetector(int pos=-1){return -1;}; + + /**removes the detector in position pos from the multidetector + \param name is the name of the detector + \returns the actual number of detectors or -1 if it failed (always for slsDetector) + */ + virtual int removeSlsDetector(char* name){return -1;}; + + /** + Turns off the server - do not use except for debugging! + */ + virtual int exitServer()=0; + + + + + /** + Loads dark image or gain image to the detector + \param index can be DARK_IMAGE or GAIN_IMAGE + \fname file name to load data from + \returns OK or FAIL + */ + virtual int loadImageToDetector(imageType index,string const fname)=0; + + + /** + writes the counter memory block from the detector + \param startACQ is 1 to start acquisition after reading counter + \fname file fname to load data from + \returns OK or FAIL + */ + virtual int writeCounterBlockFile(string const fname,int startACQ=0)=0; + + + /** + Resets counter memory block in detector + \param startACQ is 1 to start acquisition after resetting counter + \returns OK or FAIL + */ + virtual int resetCounterBlock(int startACQ=0)=0; + + /** set/get counter bit in detector + * @param i is -1 to get, 0 to reset and any other value to set the counter bit + /returns the counter bit in detector + */ + virtual int setCounterBit(int i = -1)=0; + + + /** + asks and receives all data from the detector and puts them in a data queue + \returns pointer to the front of the queue or NULL. + */ + virtual int* readAll()=0; + + + + + /** performs a complete acquisition including scansand data processing + moves the detector to next position
+ starts and reads the detector
+ reads the IC (if required)
+ reads the encoder (iof required for angualr conversion)
+ processes the data (flat field, rate, angular conversion and merging ::processData()) + \param delflag 0 leaves the data in the final data queue + \returns OK or FAIL depending on if it already started + */ + + int acquire(int delflag=1); + + + // double* convertAngles(){return convertAngles(currentPosition);}; + // virtual double* convertAngles(double pos)=0; + + virtual int setThresholdEnergy(int, int im=-1, detectorSettings isettings=GET_SETTINGS)=0; + virtual int setChannel(int64_t, int ich=-1, int ichip=-1, int imod=-1)=0; + + virtual double getRateCorrectionTau()=0; + virtual int* startAndReadAll()=0; + + virtual int getTotalNumberOfChannels()=0; + virtual int getTotalNumberOfChannels(dimension d)=0; + virtual int getMaxNumberOfChannels()=0; + virtual int getMaxNumberOfChannels(dimension d)=0; + + // virtual int getParameters(); + + + + + int setTotalProgress(); + + double getCurrentProgress(); + + + void incrementProgress(); + void setCurrentProgress(int i=0); + + + /** + write register + \param addr address + \param val value + \returns current register value + + DO NOT USE!!! ONLY EXPERT USER!!! + */ + virtual int writeRegister(int addr, int val)=0; + + + /** + write ADC register + \param addr address + \param val value + \returns current register value + + DO NOT USE!!! ONLY EXPERT USER!!! + */ + virtual int writeAdcRegister(int addr, int val)=0; + + + /** + read register + \param addr address + \returns current register value + + DO NOT USE!!! ONLY EXPERT USER!!! + */ + virtual int readRegister(int addr)=0; + /** + Returns the IP of the last client connecting to the detector + */ + virtual string getLastClientIP()=0; + + + + /** + configures mac for gotthard readout + \returns OK or FAIL + */ + + virtual int configureMAC()=0; + + + /** loads the modules settings/trimbits reading from a file + \param fname file name . If not specified, extension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + virtual int loadSettingsFile(string fname, int imod=-1)=0; + + + + /** saves the modules settings/trimbits writing to a file + \param fname file name . Axtension is automatically generated! + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + virtual int saveSettingsFile(string fname, int imod=-1)=0; + + /** sets all the trimbits to a particular value + \param val trimbit value + \param imod module number, -1 means all modules + \returns OK or FAIL + */ + virtual int setAllTrimbits(int val, int imod=-1)=0; + + + + + /** + set dacs value + \param val value (in V) + \param index DAC index + \param mV 0 in dac units or 1 in mV + \param imod module number (if -1 alla modules) + \returns current DAC value + */ + virtual dacs_t setDAC(dacs_t val, dacIndex index , int mV, int imod=-1)=0; + + + /** + gets ADC value + \param index ADC index + \param imod module number + \returns current ADC value + */ + virtual dacs_t getADC(dacIndex index, int imod=0)=0; + + /** + get the maximum size of the detector + \param d dimension + \returns maximum number of modules that can be installed in direction d + */ + virtual int getMaxNumberOfModules(dimension d=X)=0; + + double moveDetector(double pos){if (go_to_position) go_to_position (pos,GTarg); else cout << "no move detector callback registered" << endl; return getDetectorPosition();}; + double getDetectorPosition(){double pos=-1; if (get_position) pos=get_position(POarg); else cout << "no get position callback registered" << endl; return pos;}; + + /** + Writes the configuration file -- will contain all the informations needed for the configuration (e.g. for a PSI detector caldir, settingsdir, angconv, badchannels etc.) + \param fname file name + \returns OK or FAIL + */ + virtual int writeConfigurationFile(string const fname)=0; + + + void registerGetPositionCallback( double (*func)(void*),void *arg){get_position=func; POarg=arg;}; + void registerConnectChannelsCallback( int (*func)(void*),void *arg){connect_channels=func; CCarg=arg;}; + void registerDisconnectChannelsCallback(int (*func)(void*),void*arg){disconnect_channels=func;DCarg=arg;}; + + void registerGoToPositionCallback( int (*func)(double, void*),void *arg){go_to_position=func;GTarg=arg;}; + void registerGoToPositionNoWaitCallback(int (*func)(double, void*),void*arg){go_to_position_no_wait=func;GTNarg=arg;}; + void registerGetI0Callback( double (*func)(int, void*),void *arg){get_i0=func;IOarg=arg;}; + + void registerAcquisitionFinishedCallback(int( *func)(double,int, void*), void *pArg){acquisition_finished=func; acqFinished_p=pArg;}; + void registerMeasurementFinishedCallback(int( *func)(int,int, void*), void *pArg){measurement_finished=func; measFinished_p=pArg;}; + + void registerProgressCallback(int( *func)(double,void*), void *pArg){progress_call=func; pProgressCallArg=pArg;}; + + + /** + Saves the detector setup to file + \param fname file to write to + \param level if 2 reads also trimbits, flat field, angular correction etc. and writes them to files with automatically added extension + \returns OK or FAIL + + */ + int dumpDetectorSetup(string const fname, int level=0); + + + /** + Loads the detector setup from file + \param fname file to read from + \param level if 2 reads also reads trimbits, angular conversion coefficients etc. from files with default extensions as generated by dumpDetectorSetup + \returns OK or FAIL + + */ + int retrieveDetectorSetup(string const fname, int level=0); + + static int dummyAcquisitionFinished(double prog,int status,void* p){cout <<"Acquisition finished callback! " << prog << " " << status << endl; return 0;} + static int dummyMeasurementFinished(int im,int findex,void* p){cout <<"Measurement finished callback! " << im << " " << findex << endl; return 0;} + + + + + //receiver + + + /** + Checks if the receiver is really online + */ + virtual string checkReceiverOnline()=0; + + /** + Returns the IP of the last client connecting to the receiver + */ + virtual string getReceiverLastClientIP()=0; + + + /** + Sets up the file directory + @param fileName fileDir file directory + \returns file dir + */ + virtual string setFilePath(string s="")=0; + + /** + Sets up the file name + @param fileName file name + \returns file name + */ + virtual string setFileName(string s="")=0; + + /** + \returns file dir + */ + virtual string getFilePath()=0; + + /** + \returns file name + */ + virtual string getFileName()=0; + + /** + \returns frames caught by receiver + */ + virtual int getFramesCaughtByReceiver()=0; + + /** + \returns current frame index of receiver + */ +virtual int getReceiverCurrentFrameIndex()=0; + +/** + * resets framescaught + * @param index frames caught by receiver +*/ +virtual int resetFramesCaught()=0; + +/** + * Reads a frame from receiver + * @param fName file name of current frame() + * @param acquisitionIndex current acquisition index + * @param frameIndex current frame index (for each scan) + * @param subFrameIndex current sub frame index (for 32 bit mode for eiger) + /returns a frame read from recever +*/ +virtual int* readFrameFromReceiver(char* fName, int &acquisitionIndex, int &frameIndex, int &subFrameIndex)=0; + + +/** + Turns off the receiver server! +*/ +virtual int exitReceiver()=0; + +/** + Sets/Gets file overwrite enable + @param enable 1 or 0 to set/reset file overwrite enable + /returns file overwrite enable +*/ +virtual int overwriteFile(int enable=-1)=0; + + +/** + Sets/Gets receiver file write enable + @param enable 1 or 0 to set/reset file write enable + /returns file write enable +*/ +virtual int enableWriteToFile(int enable=-1)=0; + +/** Starts acquisition, calibrates pedestal and writes to fpga + /returns number of frames +*/ +virtual int calibratePedestal(int frames = 0)=0; + + +/** + set roi + \param n number of rois + \param roiLimits array of roi + \returns success or failure +*/ +virtual int setROI(int n=-1,ROI roiLimits[]=NULL)=0; + +/** + get roi from each detector and convert it to the multi detector scale + \param n number of rois + \returns an array of multidetector's rois +*/ +virtual ROI* getROI(int &n)=0; + +/** Sets the read receiver frequency + if Receiver read upon gui request, readRxrFrequency=0, + else every nth frame to be sent to gui + @param getFromReceiver is 1 if it should ask the receiver, + 0 if it can get it from multislsdetecter + @param i is the receiver read frequency + /returns read receiver frequency + */ +virtual int setReadReceiverFrequency(int getFromReceiver, int i=-1)=0; + + +/** enable/disable or get data compression in receiver + * @param i is -1 to get, 0 to disable and 1 to enable + /returns data compression in receiver + */ +virtual int enableReceiverCompression(int i = -1)=0; + +/** enable/disable or 10Gbe + * @param i is -1 to get, 0 to disable and 1 to enable + /returns if 10Gbe is enabled + */ +virtual int enableTenGigabitEthernet(int i = -1)=0; + +/** set/get receiver fifo depth + * @param i is -1 to get, any other value to set the fifo deph + /returns the receiver fifo depth + */ +virtual int setReceiverFifoDepth(int i = -1)=0; + + /******** CTB funcs */ + + /** opens pattern file and sends pattern to CTB + @param fname pattern file to open + @returns OK/FAIL + */ + virtual int setCTBPattern(string fname)=0; + + + /** Writes a pattern word to the CTB + @param addr address of the word, -1 is I/O control register, -2 is clk control register + @param word 64bit word to be written, -1 gets + @returns actual value + */ + virtual uint64_t setCTBWord(int addr,uint64_t word=-1)=0; + + /** Sets the pattern or loop limits in the CTB + @param level -1 complete pattern, 0,1,2, loop level + @param start start address if >=0 + @param stop stop address if >=0 + @param n number of loops (if level >=0) + @returns OK/FAIL + */ + virtual int setCTBPatLoops(int level,int &start, int &stop, int &n)=0; + + + /** Sets the wait address in the CTB + @param level 0,1,2, wait level + @param addr wait address, -1 gets + @returns actual value + */ + virtual int setCTBPatWaitAddr(int level, int addr=-1)=0; + + /** Sets the wait time in the CTB + @param level 0,1,2, wait level + @param t wait time, -1 gets + @returns actual value + */ + virtual int setCTBPatWaitTime(int level, uint64_t t=-1)=0; + + /** + Pulse Pixel + \param n is number of times to pulse + \param x is x coordinate + \param y is y coordinate + \returns OK or FAIL + */ + virtual int pulsePixel(int n=0,int x=0,int y=0)=0; + + /** + Pulse Pixel and move by a relative value + \param n is number of times to pulse + \param x is relative x value + \param y is relative y value + \returns OK or FAIL + */ + virtual int pulsePixelNMove(int n=0,int x=0,int y=0)=0; + + /** + Pulse Chip + \param n is number of times to pulse + \returns OK or FAIL + */ + virtual int pulseChip(int n=0)=0; + + /** + Set acquiring flag in shared memory + \param b acquiring flag + */ + virtual void setAcquiringFlag(bool b=false)=0; + + /** + Get acquiring flag from shared memory + \returns acquiring flag + */ + virtual bool getAcquiringFlag() = 0; + + + + + + + + + + + + + + + + + + + protected: + + + static const int64_t thisSoftwareVersion=0x20141013; + + + + //protected: + int *stoppedFlag; + + int64_t *timerValue; + detectorSettings *currentSettings; + int *currentThresholdEV; + + + int totalProgress; + + int progressIndex; + + double (*get_position)(void*); + int (*go_to_position)(double, void*); + int (*go_to_position_no_wait)(double, void*); + int (*connect_channels)(void*); + int (*disconnect_channels)(void*); + double (*get_i0)(int, void*); + void *POarg,*CCarg,*DCarg,*GTarg,*GTNarg,*IOarg; + int (*acquisition_finished)(double,int,void*); + int (*measurement_finished)(int,int,void*); + void *acqFinished_p, *measFinished_p; + + + + int (*progress_call)(double,void*); + void *pProgressCallArg; + +}; + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/AngularConversion_Standalone.cpp b/slsDetectorSoftware/slsDetectorAnalysis/AngularConversion_Standalone.cpp new file mode 100644 index 000000000..36f40e2bd --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/AngularConversion_Standalone.cpp @@ -0,0 +1,527 @@ +#include "AngularConversion_Standalone.h" + +#include +#include +#include +#include +#include "usersFunctions.h" + +using namespace std; + +angularConversion::angularConversion( int *np, double *pos, double *bs, double *fo, double *go): currentPosition(0), + currentPositionIndex(0), + numberOfPositions(np), + detPositions(pos), + binSize(bs), + fineOffset(fo), + globalOffset(go) + +{ + //angleFunctionPointer=0; + registerAngleFunctionCallback(&defaultAngleFunction,NULL); + registerCallBackGetChansPerMod(&defaultGetChansPerMod,this); + registerCallBackGetNumberofChannel(&defaultGetNumberofChannel,this); +} + +angularConversion::~angularConversion(){ + +} + +// int angularConversion::setAngularConversionPointer(angleConversionConstant *p, int *nm, int nch, int idet) { +// if (p) { +// angOff[idet]=p; +// nMods[idet]=nm; +// nCh[idet]=nch; +// } else { +// angOff[idet]=NULL; +// nMods[idet]=NULL; +// } + +// return OK; +// } + + + + +double* angularConversion::convertAngles(double pos) { + int imod=0; + double *ang=new double[totalNumberOfChannels]; + double enc=pos; + angleConversionConstant *p=NULL; + + int ch0=0; + int chlast=getChansPerMods(imod); + int nchmod=getChansPerMods(imod); + p=angConvs+imod; + if (moveFlag[imod]==0) + enc=0; + else + enc=pos; + + for (int ip=0; ip=chlast) { + imod++; + p=angConvs+imod; + if (moveFlag[imod]==0) + enc=0; + else + enc=pos; + + ch0=chlast; + nchmod=getChansPerMods(imod); + if (nchmod>0) + chlast+=nchmod; + } + + if (p) + ang[ip]=angle(ip-ch0, \ + enc, \ + (*fineOffset)+(*globalOffset), \ + p->r_conversion, \ + p->center, \ + p->offset, \ + p->tilt, \ + *angDirection ); + } + return ang; +} + + + +//static! +int angularConversion::readAngularConversion(string fname, int nmod, angleConversionConstant *angOff) { + + ifstream infile; + string ss; + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + readAngularConversion(infile, nmod, angOff); + infile.close(); + } else { + std::cout<< "Could not open calibration file "<< fname << std::endl; + return -1; + } + return 0; +} + + +//static +int angularConversion::readAngularConversion( ifstream& infile, int nmod, angleConversionConstant *angOff) { + string str; + int mod; + double center, ecenter; + double r_conv, er_conv; + double off, eoff; + string ss; + int interrupt=0; + int nm=0; + //" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n" + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + cout << "** mod " << nm << " " ; + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> ss >> mod; + ssstr >> ss >> center; + ssstr >> ss >> ecenter; + ssstr >> ss >> r_conv; + ssstr >> ss >> er_conv; + ssstr >> ss >> off; + ssstr >> ss >> eoff; + if (nm=0 ) { + angOff[nm].center=center; + angOff[nm].r_conversion=r_conv; + angOff[nm].offset=off; + angOff[nm].ecenter=ecenter; + angOff[nm].er_conversion=er_conv; + angOff[nm].eoffset=eoff; + } else + break; + //cout << nm<<" " << angOff[nm].offset << endl; + nm++; + if (nm>=nmod) + break; + + } + return nm; + } + +//static +int angularConversion:: writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff) { + + ofstream outfile; + outfile.open (fname.c_str(),ios_base::out); + if (outfile.is_open()) + { + writeAngularConversion(outfile, nmod, angOff); + outfile.close(); + } else { + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; + return -1; + } + //" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n" + return 0; +} + + + +//static +int angularConversion:: writeAngularConversion(ofstream& outfile, int nmod, angleConversionConstant *angOff) { + + for (int imod=0; imod0) { + +#ifdef VERBOSE + cout << "finalize " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl; +#endif + mp[np]=mp[ibin]/mm[ibin]; + mv[np]=mv[ibin]/mm[ibin]; + me[np]=me[ibin]/mm[ibin]; + me[np]=sqrt(me[ibin]); + mm[np]=mm[ibin]; + np++; + } + } + return np; +} + +//static +int angularConversion::addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nbins, int *badChanMask ) { + + + double binmi=-180.; + int ibin=0; + + if (p1==NULL) + return 0; + if (v1==NULL) + return FAIL; + + if (mp==NULL) //can be changed if we want to use a fixed bin algorithm! + return FAIL; + + if (mv==NULL) + return FAIL; + if (me==NULL) + return FAIL; + if (mm==NULL) + return FAIL; + if (nchans==0) + return FAIL; + + if (binsize<=0) + return FAIL; + + if (nbins<=0) + return FAIL; + + for (int ip=0; ip=0) { + mp[ibin]+=p1[ip]; + mv[ibin]+=v1[ip]; + if (e1) + me[ibin]+=(e1[ip]*e1[ip]); + else + me[ibin]+=v1[ip]; + mm[ibin]++; + +#ifdef VERBOSE + cout << "add " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl; +#endif + } else + return FAIL; + } + + + return OK; + +} + +int angularConversion::deleteMerging() { + + if (mergingBins) + delete [] mergingBins; + + if (mergingCounts) + delete [] mergingCounts; + + if (mergingErrors) + delete [] mergingErrors; + +} + + +int angularConversion::resetMerging() { + getAngularConversionParameter(BIN_SIZE); + + mergingBins=new double[nBins]; + + + mergingCounts=new double[nBins]; + + + mergingErrors=new double[nBins]; + + + mergingMultiplicity=new int[nBins]; + + return resetMerging(mergingBins, mergingCounts, mergingErrors, mergingMultiplicity); + +} + +int angularConversion::resetMerging(double *mp, double *mv, double *me, int *mm) { + getAngularConversionParameter(BIN_SIZE); + if (nBins) + return resetMerging(mp, mv, me, mm,nBins); + else + return FAIL; +} + + + + +int angularConversion::finalizeMerging() { + int np=finalizeMerging(mergingBins, mergingCounts, mergingErrors, mergingMultiplicity); + + if (mergingMultiplicity) + delete [] mergingMultiplicity; + + return np; + +} + + + + +int angularConversion::finalizeMerging(double *mp, double *mv, double *me, int *mm) { + if (nBins) + return finalizeMerging(mp, mv, me, mm, nBins); + else + return FAIL; +} + +int angularConversion::addToMerging(double *p1, double *v1, double *e1, int *badChanMask ) { + + return addToMerging(p1,v1,e1,mergingBins,mergingCounts, mergingErrors, mergingMultiplicity, badChanMask); + + +} + + +int angularConversion::addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int *badChanMask ) { + + int del=0; + + if (getAngularConversionParameter(BIN_SIZE)==0){ + cout << "no bin size " << endl; + return FAIL; + } + + if (nBins==0) { + cout << "no bins " << endl; + return FAIL; + } + + if (p1==NULL) { + del=1; + p1=convertAngles(); + } + + + int ret=addToMerging(p1, v1, e1, mp, mv,me, mm,getTotalNumberofChannels(), *binSize,nBins, badChanMask ); + + + if (del) { + delete [] p1; + p1=NULL; + } + return ret; +} + + + + /** + sets the value of s angular conversion parameter + \param c can be ANGULAR_DIRECTION, GLOBAL_OFFSET, FINE_OFFSET, BIN_SIZE + \param v the value to be set + \returns the actual value + */ + +double angularConversion::setAngularConversionParameter(angleConversionParameter c, double v){ + + + switch (c) { + case ANGULAR_DIRECTION: + if (v<0) + *angDirection=-1; + else + *angDirection=1; + return *angDirection; + case GLOBAL_OFFSET: + *globalOffset=v; + return *globalOffset; + case FINE_OFFSET: + *fineOffset=v; + return *fineOffset; + case BIN_SIZE: + if (v>0) { + *binSize=v; + nBins=360./(*binSize); + } + return *binSize; + case MOVE_FLAG: + if (moveFlag) { + if (v>0) + *moveFlag=1; + else if (v==0) + *moveFlag=0; + return *moveFlag; + } + return -1; + default: + return 0; + } +} + + /** + returns the value of an angular conversion parameter + \param c can be ANGULAR_DIRECTION, GLOBAL_OFFSET, FINE_OFFSET, BIN_SIZE + \returns the actual value + + */ + +double angularConversion::getAngularConversionParameter(angleConversionParameter c) { + + switch (c) { + case ANGULAR_DIRECTION: + return *angDirection; + case GLOBAL_OFFSET: + return *globalOffset; + case FINE_OFFSET: + return *fineOffset; + case BIN_SIZE: + if (*binSize>0) + nBins=360./(*binSize); + else + nBins=0; + return *binSize; + case MOVE_FLAG: + if (moveFlag) + return *moveFlag; + else + return -1; + default: + return 0; + } +} + + + +/** +int angularConversion::setAngularConversionFile(string fname) { + if (fname=="") { + setAngularCorrectionMask(0); +#ifdef VERBOSE + std::cout << "Unsetting angular conversion" << std::endl; +#endif + } else { + if (fname=="default") { + fname=string(angConvFile); + } + +#ifdef VERBOSE + std::cout << "Setting angular conversion to " << fname << std:: endl; +#endif + if (readAngularConversionFile(fname)>=0) { + setAngularCorrectionMask(1); + strcpy(angConvFile,fname.c_str()); + } + } + return setAngularCorrectionMask(); +} + + +*/ + + + /* + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ +int angularConversion::setPositions(int nPos, double *pos){ + if (nPos>=0) + *numberOfPositions=nPos; + for (int ip=0; ip +#include + + + + //double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) + + +using namespace std; + +/** + @short Angular conversion constants needed for a detector module + */ +typedef struct { + double center; /**< center of the module (channel at which the radius is perpendicular to the module surface) */ + double ecenter; /**< error in the center determination */ + double r_conversion; /**< detector pixel size (or strip pitch) divided by the diffractometer radius */ + double er_conversion; /**< error in the r_conversion determination */ + double offset; /**< the module offset i.e. the position of channel 0 with respect to the diffractometer 0 */ + double eoffset; /**< error in the offset determination */ + double tilt; /**< ossible tilt in the orthogonal direction (unused)*/ + double etilt; /**< error in the tilt determination */ +} angleConversionConstant; + + +/** + +@short methods to set/unset the angular conversion and merge the data +class containing the methods to set/unset the angular conversion and merge the data + + +The angular conversion itself is defined by the angle() function defined in usersFunctions.cpp + +*/ +class angularConversion : public virtual slsDetectorDefs { //: public virtual slsDetectorBase { + + public: + /** default constructor */ + angularConversion(int*, double*, double*, double*, double*); + /** virtual destructor */ + virtual ~angularConversion(); + + + + //virtual int readAngularConversion(string fname)=0; + + + + + /** + + reads an angular conversion file + \param fname file to be read + \param nmod number of modules (maximum) to be read + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + */ + static int readAngularConversion(string fname, int nmod, angleConversionConstant *angOff); + + /** + reads an angular conversion file + \param ifstream input file stream to be read + \param nmod number of modules (maximum) to be read + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + + */ + static int readAngularConversion(ifstream& ifs, int nmod, angleConversionConstant *angOff); + /** + writes an angular conversion file + \param fname file to be written + \param nmod number of modules to be written + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + */ + static int writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff); + + /** + writes an angular conversion file + \param ofstream output file stream + \param nmod number of modules to be written + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + */ + static int writeAngularConversion(ofstream& ofs, int nmod, angleConversionConstant *angOff); + + /** + sets the arrays of the merged data to 0. NB The array should be created with size nbins >= 360./getBinSize(); + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param nbins number of bins + \returns OK or FAIL + */ + static int resetMerging(double *mp, double *mv,double *me, int *mm, int nbins); + /** + sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns OK or FAIL + */ + int resetMerging(double *mp, double *mv,double *me, int *mm); + + /** + creates the arrays for merging the data and sets them to 0. + */ + int resetMerging(); + + /** + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param nchans number of channels + \param binsize size of angular bin + \param nb number of angular bins + \param badChanMask badchannelmask (if NULL does not correct for bad channels) + \returns OK or FAIL + */ + + static int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nb, int *badChanMask ); + + /** + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param badChanMask badchannelmask (if NULL does not correct for bad channels) + \returns OK or FAIL + */ + + int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int *badChanMask); + /** + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param badChanMask badchannelmask (if NULL does not correct for bad channels) + \returns OK or FAIL + */ + + int addToMerging(double *p1, double *v1, double *e1,int *badChanMask); + + /** + calculates the "final" positions, data value and errors for the merged data + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param nb number of bins + \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) + */ + + static int finalizeMerging(double *mp, double *mv,double *me, int *mm, int nb); + /** + calculates the "final" positions, data value and errors for the merged data + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) + */ + + int finalizeMerging(double *mp, double *mv,double *me, int *mm); + +/** + calculates the "final" positions, data value and errors for the merged data + \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) + */ + + int finalizeMerging(); + + + /** + set detector global offset + \param f global offset to be set + \returns actual global offset + */ + double setGlobalOffset(double f){return setAngularConversionParameter(GLOBAL_OFFSET,f);}; + + + /** + set detector fine offset + \param f global fine to be set + \returns actual fine offset + */ + double setFineOffset(double f){return setAngularConversionParameter(FINE_OFFSET,f);}; + + /** + get detector fine offset + \returns actual fine offset + */ + double getFineOffset(){return getAngularConversionParameter(FINE_OFFSET);}; + + /** + get detector global offset + \returns actual global offset + */ + double getGlobalOffset(){return getAngularConversionParameter(GLOBAL_OFFSET);}; + + /** + + set detector bin size + \param bs bin size to be set + \returns actual bin size + */ + double setBinSize(double bs){if (bs>0) nBins=360/bs; return setAngularConversionParameter(BIN_SIZE,bs);}; + + /** + get detector bin size + \returns detector bin size used for merging (approx angular resolution) + */ + double getBinSize() {return getAngularConversionParameter(BIN_SIZE);}; + + + + /** + + get angular direction + \returns actual angular direction (1 is channel number increasing with angle, -1 decreasing) + */ + int getAngularDirection(){return (int)getAngularConversionParameter(ANGULAR_DIRECTION);}; + + + /** + + set angular direction + \param d angular direction to be set (1 is channel number increasing with angle, -1 decreasing) + \returns actual angular direction (1 is channel number increasing with angle, -1 decreasing) + */ + int setAngularDirection(int d){return (int)setAngularConversionParameter(ANGULAR_DIRECTION, (double)d);}; + + /** + \returns number of angular bins in the merging (360./binsize) + */ + int getNumberOfAngularBins(){return nBins;}; + + + + /** + set angular conversion parameter + \param c parameter type (globaloffset, fineoffset, binsize, angular direction, move flag) + \param v value to be set + \returns actual value + */ + double setAngularConversionParameter(angleConversionParameter c, double v); + /** + get angular conversion parameter + \param c parameter type (globaloffset, fineoffset, binsize, angular direction, move flag) + \returns actual value + */ + double getAngularConversionParameter(angleConversionParameter c); + + + + + /** + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ + virtual int setPositions(int nPos, double *pos); + /** + get positions for the acquisition + \param pos array which will contain the encoder positions + \returns number of positions + */ + virtual int getPositions(double *pos=NULL); + + /** + deletes the array of merged data + \returns OK + */ + int deleteMerging(); + + /** + \returns pointer to the array o merged positions + */ + double *getMergedPositions(){return mergingBins;}; + /** + \returns pointer to the array of merged counts + */ + double *getMergedCounts(){return mergingCounts;}; + /** + \returns pointer to the array of merged errors + */ + double *getMergedErrors(){return mergingErrors;}; + + + + +/* /\** */ +/* reads teh angular conversion file for the (multi)detector and writes it to shared memory */ +/* *\/ */ +/* virtual int readAngularConversionFile(string fname="")=0; */ + +/* /\** */ +/* get angular conversion */ +/* \param direction reference to diffractometer direction */ +/* \param angconv array that will be filled with the angular conversion constants */ +/* \returns 0 if angular conversion disabled, >0 otherwise */ +/* *\/ */ + virtual int getAngularConversion(int &direction, angleConversionConstant *angoff=NULL); + +/* /\** */ +/* pure virtual function */ +/* \param file name to be written (nmod and array of angular conversion constants default to the ones ot the slsDetector */ +/* *\/ */ +/* virtual int writeAngularConversion(string fname)=0; */ + + + + +/* /\** */ +/* \returns number of modules of the (multi)detector */ +/* *\/ */ +/* virtual int getNMods()=0; */ + +/* /\** */ +/* returns number of channels in the module */ +/* \param imod module number */ +/* \returns number of channels in the module */ +/* *\/ */ + + + static int defaultGetNumberofChannel(int nch, void *p=NULL ) { ((angularConversion*)p)->setTotalNumberOfChannels(nch); return 0;}; + static int defaultGetChansPerMod(int imod=0, void *p=NULL){ ((angularConversion*)p)->setChansPerMod(0,imod); return 0;}; + + int setChansPerMod(int nch, int imod=0){if (nch<0) return -1; if (imod>=0 && imod=0){ totalNumberOfChannels=i; return totalNumberOfChannels;} else return -1;}; + + +/* /\** */ +/* get the angular conversion contant of one modules */ +/* \param imod module number */ +/* \returns pointer to the angular conversion constant */ +/* *\/ */ +/* virtual angleConversionConstant *getAngularConversionPointer(int imod=0)=0; */ +/* /\** */ +/* \param imod module number */ +/* \returns move flag of the module (1 encoder is added to the angle, 0 not) */ +/* *\/ */ +/* virtual int getMoveFlag(int imod)=0; */ + +/* /\** */ +/* enables/disable the angular conversion */ +/* \param i 1 sets, 0 unsets,, -1 gets */ +/* \returns actual angular conversion flag */ +/* *\/ */ +/* virtual int setAngularCorrectionMask(int i=-1)=0; */ + + + + /** + converts channel number to angle + \param pos encoder position + \returns array of angles corresponding to the channels + */ + double* convertAngles(double pos); + /** + converts channel number to angle for the current encoder position + \returns array of angles corresponding to the channels + */ + double *convertAngles(){return convertAngles(currentPosition);}; + + + /** + returns number of positions + */ + int getNumberOfPositions() {return *numberOfPositions;}; + + int getChansPerMods(int imod) { return chansPerMod[imod];}; + int getTotalNumberofChannels(){ return totalNumberOfChannels;}; + + + void incrementPositionIndex() {currentPositionIndex++;}; + + void registerCallBackGetChansPerMod(int (*func)(int, void *),void *arg){ getChansPerModule=func;pChpermod=arg;}; + void registerCallBackGetNumberofChannel(int (*func)(int, void *),void *arg){ getNumberofChannel=func;pNumberofChannel=arg;}; + + protected: + + + + private: + + + int (*getChansPerModule)(int, void*); + int (*getNumberofChannel)(int, void*); + + void *pChpermod,*angPtr,*pNumberofChannel; + + + /** merging bins */ + double *mergingBins; + + /** merging counts */ + double *mergingCounts; + + /** merging errors */ + double *mergingErrors; + + /** merging multiplicity */ + int *mergingMultiplicity; + + double (*angle)(double, double, double, double, double, double, double, int); + + + + int totalNumberOfChannels; + + int moveFlag[MAXMODS*MAXDET]; + + /** pointer to number of positions for the acquisition*/ + int *numberOfPositions; + + /** pointer to the detector positions for the acquisition*/ + double *detPositions; + + + /** pointer to angular bin size*/ + double *binSize; + + int *correctionMask; + int chansPerMod[MAXMODS*MAXDET]; + int nMod; + angleConversionConstant angConvs[MAXMODS*MAXDET]; + int directions[MAXMODS*MAXDET]; + + + /** pointer to beamline fine offset*/ + double *fineOffset; + /** pointer to beamline global offset*/ + double *globalOffset; + /** pointer to beamline angular direction*/ + int *angDirection; + + /** pointer to detector move flag (1 moves with encoder, 0 not)*/ + // int *moveFlag; + + /** number of bins for angular conversion (360./binsize)*/ + int nBins; + + + + /** + current position of the detector + */ + double currentPosition; + /** + current position index of the detector + */ + int currentPositionIndex; + + + /** + returns current position index + */ + int getCurrentPositionIndex() {return currentPositionIndex;}; + + + + + + void registerAngleFunctionCallback(double( *fun)(double, double, double, double, double, double, double, int),void* arg) {angle = fun; angPtr=arg;}; + + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.cpp b/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.cpp new file mode 100644 index 000000000..27bee95b3 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.cpp @@ -0,0 +1,650 @@ +#include "FileIO_Standalone.h" + + + + + +string fileIO::createFileName(char *filepath, char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos, int findex) { + ostringstream osfn; + // string fn; + /*directory name +root file name */ + osfn << filepath << "/" << filename; + + // cout << osfn.str() << endl; + + // scan level 0 + if ( aMask& (1 << (MAX_ACTIONS))) + osfn << "_S" << fixed << setprecision(prec0) << sv0; + + //cout << osfn.str() << endl; + + //scan level 1 + if (aMask & (1 << (MAX_ACTIONS+1))) + osfn << "_s" << fixed << setprecision(prec1) << sv1; + + //cout << osfn.str() << endl; + + + //position + if (pindex>0 && pindex<=npos) + osfn << "_p" << pindex; + + //cout << osfn.str() << endl; + + // file index + osfn << "_" << findex; + + //cout << osfn.str() << endl; + + +#ifdef VERBOSE + cout << "created file name " << osfn.str() << endl; +#endif + + //cout << osfn.str() << endl; + //fn=oosfn.str()sfn.str(); + return osfn.str(); + +} + + + /* I/O */ + +/* generates file name without extension*/ + +string fileIO::createFileName(int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos) { + currentFileName=createFileName(filePath, \ + fileName, \ + aMask, \ + sv0, \ + prec0, \ + sv1, \ + prec1, \ + pindex, \ + npos, \ + *fileIndex \ + ); + return currentFileName; + +} + + +int fileIO::getFileIndexFromFileName(string fname) { + int i; + size_t dot=fname.rfind("."); + if (dot==string::npos) + return -1; + size_t uscore=fname.rfind("_"); + if (uscore==string::npos) + return -1; + + if (sscanf( fname.substr(uscore+1,dot-uscore-1).c_str(),"%d",&i)) { + + return i; + } + //#ifdef VERBOSE + cout << "******************************** cannot parse file index" << endl; + //#endif + return 0; +} + +int fileIO::getVariablesFromFileName(string fname, int &index, int &p_index, double &sv0, double &sv1) { + + int i; + double f; + string s; + + + index=-1; + p_index=-1; + sv0=-1; + sv1=-1; + + + // size_t dot=fname.rfind("."); + //if (dot==string::npos) + // return -1; + size_t uscore=fname.rfind("_"); + if (uscore==string::npos) + return -1; + s=fname; + + //if (sscanf(s.substr(uscore+1,dot-uscore-1).c_str(),"%d",&i)) { + if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)) { + index=i; +#ifdef VERBOSE + cout << "******************************** file index is " << index << endl; +#endif + //return i; + s=fname.substr(0,uscore); + } + else + cout << "******************************** cannot parse file index" << endl; + +#ifdef VERBOSE + cout << s << endl; +#endif + + + uscore=s.rfind("_"); + + + + + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"p%d",&i)) { + p_index=i; +#ifdef VERBOSE + cout << "******************************** position index is " << p_index << endl; +#endif + s=fname.substr(0,uscore); + } + else + cout << "******************************** cannot parse position index" << endl; + +#ifdef VERBOSE + cout << s << endl; +#endif + + + + + uscore=s.rfind("_"); + + + + + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"s%f",&f)) { + sv1=f; +#ifdef VERBOSE + cout << "******************************** scan variable 1 is " << sv1 << endl; +#endif + s=fname.substr(0,uscore); + } + else + cout << "******************************** cannot parse scan varable 1" << endl; + +#ifdef VERBOSE + cout << s << endl; + + +#endif + + uscore=s.rfind("_"); + + + + + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"S%f",&f)) { + sv0=f; +#ifdef VERBOSE + cout << "******************************** scan variable 0 is " << sv0 << endl; +#endif + } + else + cout << "******************************** cannot parse scan varable 0" << endl; + +#ifdef VERBOSE +#endif + + + + return index; +} + + + + + +int fileIO::writeDataFile(string fname, int nch, double *data, double *err, double *ang, char dataformat){ + + + ofstream outfile; + // int idata; + if (data==NULL) + return FAIL; + + // args|=0x10; // one line per channel! + + outfile.open (fname.c_str(),ios_base::out); + if (outfile.is_open()) + { + writeDataFile(outfile, nch, data, err, ang, dataformat, 0); + outfile.close(); + return OK; + } else { + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; + return FAIL; + } +}; + + +int fileIO::writeDataFile(ofstream &outfile, int nch, double *data, double *err, double *ang, char dataformat, int offset){ + + + int idata; + if (data==NULL) + return FAIL; + + // args|=0x10; // one line per channel! + + cout << "Static file " << endl; + + + for (int ichan=0; ichan> ichan >> fdata; + //ich=ichan; + if (ssstr.fail() || ssstr.bad()) { + interrupt=1; + break; + } + // if (ich!=iline) + // std::cout<< "Channel number " << ichan << " does not match with line number " << iline << " " << dataformat << std::endl; + ich=iline; + if (ichan> fang >> fdata; + ich=iline; + } + if (ssstr.fail() || ssstr.bad()) { + interrupt=1; + break; + } + if (err) + ssstr >> ferr; + if (ssstr.fail() || ssstr.bad()) { + interrupt=1; + break; + } + if (ich=nch) { + interrupt=1; + break; + } + } + return iline; +}; + + + +int fileIO::readDataFile(string fname, int *data, int nch){ + + ifstream infile; + int iline=0;//ichan, idata, + //int interrupt=0; + string str; + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + iline=readDataFile(infile, data, nch, 0); + infile.close(); + } else { + std::cout<< "Could not read file " << fname << std::endl; + return -1; + } + return iline; +}; + +int fileIO::readDataFile(ifstream &infile, int *data, int nch, int offset){ + + int ichan, idata, iline=0; + int interrupt=0; + string str; + + + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> ichan >> idata; + if (ssstr.fail() || ssstr.bad()) { + interrupt=1; + break; + } + // if (ichan!=iline) { +// std::cout<< " Expected channel "<< iline <<" but read channel "<< ichan << std::endl; +// interrupt=1; +// break; +// } else { + if (iline=offset) { + data[iline]=idata; + iline++; + } + } else { + interrupt=1; + break; + } + // } + } + return iline; +}; + + +int fileIO::readDataFile(string fname, short int *data, int nch){ + + ifstream infile; + int iline=0;//ichan, + //int interrupt=0; + string str; + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + iline=readDataFile(infile, data, nch, 0); + infile.close(); + } else { + std::cout<< "Could not read file " << fname << std::endl; + return -1; + } + return iline; +}; + +int fileIO::readDataFile(ifstream &infile, short int *data, int nch, int offset){ + + int ichan, iline=0; + short int idata; + int interrupt=0; + string str; + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + ;//std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> ichan >> idata; + if (ssstr.fail() || ssstr.bad()) { + interrupt=1; + break; + } + // if (ichan!=iline) { +// std::cout<< " Expected channel "<< iline <<" but read channel "<< ichan << std::endl; +// interrupt=1; +// break; +// } else { + if (iline=offset) { + data[iline]=idata; + iline++; + } + } else { + interrupt=1; + break; + } + // } +#ifdef VERBOSE + ;//std::cout<< "read " << iline <<" channels " << std::endl; +#endif + } + return iline; +} + + + +/*writes raw data file */ + +int fileIO::writeDataFile(string fname, double *data, double *err, double *ang, char dataformat, int nch){ + if (nch==-1) + nch=getTotalNumberofChannels();//getTotalNumberOfChannels(); + + return writeDataFile(fname, nch, data, err, ang, dataformat); + +} +int fileIO::writeDataFile(ofstream &outfile, double *data, double *err, double *ang, char dataformat, int nch, int offset){ + if (nch==-1) + nch=getTotalNumberofChannels(); + + return writeDataFile(outfile, nch, data, err, ang, dataformat, offset); + +} + + + + +int fileIO::writeDataFile(string fname, int *data){ + + return writeDataFile(fname, getTotalNumberofChannels(), data); +} + +int fileIO::writeDataFile(ofstream &outfile, int *data, int offset){ + + return writeDataFile(outfile, getTotalNumberofChannels(), data, offset); +} + + + + + +int fileIO::writeDataFile(string fname, short int *data){ + + return writeDataFile(fname, getTotalNumberofChannels(), data); +} + +int fileIO::writeDataFile(ofstream &outfile, short int *data, int offset){ + + return writeDataFile(outfile,getTotalNumberofChannels() , data, offset); +} + + + + +int fileIO::readDataFile(string fname, double *data, double *err, double *ang, char dataformat) { + return readDataFile(getTotalNumberofChannels(), fname, data, err, ang, dataformat); + +} + +int fileIO::readDataFile(ifstream &infile, double *data, double *err, double *ang, char dataformat, int offset) { + return readDataFile(getTotalNumberofChannels(), infile, data, err, ang, dataformat, offset); + +} + + + +int fileIO::readDataFile(string fname, int *data){ + + return readDataFile(fname, data, getTotalNumberofChannels()); +}; + + +int fileIO::readDataFile(ifstream &infile, int *data, int offset){ + + return readDataFile(infile, data, getTotalNumberofChannels(), offset); +}; + + + + + +int fileIO::readDataFile(string fname, short int *data){ + + return readDataFile(fname, data, getTotalNumberofChannels()); +}; + + +int fileIO::readDataFile(ifstream &infile, short int *data, int offset){ + + return readDataFile(infile, data, getTotalNumberofChannels(),offset); +}; + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.h b/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.h new file mode 100644 index 000000000..1056c9879 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/FileIO_Standalone.h @@ -0,0 +1,410 @@ +#ifndef FILEIOSTD_H +#define FILEIOSTD_H + +//#include "slsDetectorBase.h" +#include "sls_detector_defs.h" +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +/** + @short class handling the data file I/O flags +*/ + +class fileIO : public virtual slsDetectorDefs {//public virtual slsDetectorBase { + + + + public: + /** default constructor */ + fileIO(){}; + /** virtual destructor */ + virtual ~fileIO(){}; + + int setTotalNumberofChannels(int i){ if (i>=0) {totalNumberofChannels=i; return totalNumberofChannels;} else return -1;}; + int getTotalNumberofChannels(){ return totalNumberofChannels; }; + /** + sets the default output files path + \param s file path + \return actual file path + */ + string setFilePath(string s) {sprintf(filePath, s.c_str()); return string(filePath);}; + + /** + sets the default output files root name + \param s file name to be set + \returns actual file name + */ + string setFileName(string s) {sprintf(fileName, s.c_str()); return string(fileName);}; + + /** + sets the default output file index + \param i start file index to be set + \returns actual file index + */ + int setFileIndex(int i) {*fileIndex=i; return *fileIndex;}; + + + + /** + \returns the output files path + + */ + string getFilePath() {return string(filePath);}; + + /** + \returns the output files root name + */ + string getFileName() {return string(fileName);}; + + /** + \returns the output file index + */ + int getFileIndex() {return *fileIndex;}; + + + + + + + /** generates file name without extension + + always appends to file path and file name the run index. + + in case also appends the position index and the two level of scan varaibles with the specified precision + + Filenames will be of the form: filepath/filename(_Sy_sw_px)_i + where y is the scan0 variable, W is the scan 1 variable, x is the position index and i is the run index + \param filepath outdir + \param filename file root name + \param aMask action mask (scans, positions) + \param sv0 scan variable 0 + \param prec0 scan precision 0 + \param sv1 scan variable 1 + \param prec1 scan precision 1 + \param pindex position index + \param number of positions + \param findex file index + \returns file name without extension + */ + static string createFileName(char *filepath, char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos, int findex); + + + string createFileName(int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos); + + + /** static function that returns the file index from the file name + \param fname file name + \returns file index + */ + int getFileIndexFromFileName(string fname); + + /** static function that returns the variables from the file name + \param fname file name + \param index reference to index + \param p_index reference to position index + \param sv0 reference to scan variable 0 + \param sv1 reference to scan variable 1 + \returns file index + */ + static int getVariablesFromFileName(string fname, int &index, int &p_index, double &sv0, double &sv1); + + + + + /** + + writes a data file + \param fname of the file to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not write the file or data=NULL + + */ + virtual int writeDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1); + + + /** + + writes a data file + \paramoutfile output file stream + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + + */ + int writeDataFile(ofstream &outfile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1, int offset=0); + + + /** + writes a data file + \param fname of the file to be written + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + */ + virtual int writeDataFile(string fname, int *data); + + /** + writes a data file + \param outfile output file stream + \param data array of data values + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + int writeDataFile(ofstream &outfile, int *data, int offset=0); + + + + /** + writes a data file of short ints + \param fname of the file to be written + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + */ + virtual int writeDataFile(string fname, short int *data); + + /** + writes a data file of short ints + \param outfile output file stream + \param data array of data values + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + int writeDataFile(ofstream &outfile, short int *data, int offset=0); + + + /** + reads a data file + \param fname of the file to be read + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \returns OK or FAIL if it could not read the file or data=NULL + */ + virtual int readDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); + + /** + reads a data file + \param ifstream input file stream + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param offset start channel number to be expected + \returns OK or FAIL if it could not read the file or data=NULL + */ + int readDataFile(ifstream& infile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0); + + /** + reads a raw data file + \param fname of the file to be read + \param data array of data values + \returns OK or FAIL if it could not read the file or data=NULL + */ + virtual int readDataFile(string fname, int *data); /** + reads a raw data file + \param infile input file stream + \param data array of data values + \param offset first channel number to be expected + \returns OK or FAIL if it could not read the file or data=NULL + */ + int readDataFile(ifstream &infile, int *data, int offset=0); + + /** + + reads a short int raw data file + \param fname of the file to be read + \param data array of data values + \returns OK or FAIL if it could not read the file or data=NULL + */ + virtual int readDataFile(string fname, short int *data); + /** + reads a short int raw data file + \param infile input file stream + \param data array of data values + \param offset first channel number to be expected + \returns OK or FAIL if it could not read the file or data=NULL + */ + int readDataFile(ifstream &infile, short int *data, int offset=0); + + /** + + writes a data file + \param fname of the file to be written + \param nch number of channels to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \returns OK or FAIL if it could not write the file or data=NULL + + */ + + static int writeDataFile(string fname, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); + /** + writes a data file + \param outfile output file stream + \param nch number of channels to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + static int writeDataFile(ofstream &outfile, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0); + + /** + writes a raw data file + \param fname of the file to be written + \param nch number of channels + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + */ + static int writeDataFile(string fname,int nch, int *data); + + /** + writes a raw data file + \param outfile output file stream + \param nch number of channels + \param data array of data values + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + static int writeDataFile(ofstream &outfile,int nch, int *data, int offset=0); + + + /** + + writes a short int raw data file + \param fname of the file to be written + \param nch number of channels + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + */ + static int writeDataFile(string fname,int nch, short int *data); + + /** + writes a short int raw data file + \param outfile output file stream + \param nch number of channels + \param data array of data values + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + static int writeDataFile(ofstream &outfile,int nch, short int *data, int offset=0); + + + /** + reads a data file + \param nch number of channels + \param fname of the file to be read + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \returns number of channels read or -1 if it could not read the file or data=NULL + + */ + static int readDataFile(int nch, string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); + /** + reads a data file + \param nch number of channels + \param infile input file stream + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param offset start channel number + \returns number of channels read or -1 if it could not read the file or data=NULL + + */ + static int readDataFile(int nch, ifstream &infile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0); + + /** + reads a raw data file + \param fname of the file to be read + \param data array of data values + \param nch number of channels + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(string fname, int *data, int nch); + + /** + reads a raw data file + \param infile input file stream + \param data array of data values + \param nch number of channels + \param offset start channel value + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(ifstream &infile, int *data, int nch, int offset); + + /** + reads a short int rawdata file + \param name of the file to be read + \param data array of data values + \param nch number of channels + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(string fname, short int *data, int nch); + /** + reads a short int raw data file + \param infile input file stream + \param data array of data values + \param nch number of channels + \param offset start channel value + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(ifstream &infile, short int *data, int nch, int offset); + + + + + + void incrementFileIndex() { (*fileIndex)++;}; + + string getCurrentFileName(){return currentFileName;}; + + protected: + string currentFileName; + + + int mask_action; + double currentscan_variable[1]; + int scan_precision[1]; + int currentpostion_i; + int noposition; + + /** output directory */ + char *filePath; + /** file root name */ + char *fileName; + /** file index */ + int *fileIndex; + + private: + + int totalNumberofChannels; + + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/Makefile b/slsDetectorSoftware/slsDetectorAnalysis/Makefile new file mode 100644 index 000000000..1b137d512 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/Makefile @@ -0,0 +1,87 @@ +#--------------------------------------------------- + + +include Makefile.arch + +#------------------------------------------------------------------------------ + +SLSDETO = TSlsDetectorDict.$(ObjSuf) energyCalibration.$(ObjSuf) angularCalibration.$(ObjSuf) + +SLSDETSO = libTSlsDetector.$(DllSuf) + +CXXFLAGS += -Wno-deprecated +#LIBS += -L../slsDetectorSoftware -lSlsDetector -pthread + +CXXFLAGS += -I ../usersFunctions + +HEADERS= energyCalibration.h angularCalibration.h +#------------------------------------------------------------------------------- + +#----------- do the shared library +$(SLSDETSO): $(SLSDETO) + @echo "Generating shared library $@..." + $(LD) $(SOFLAGS) $(LDFLAGS) -o $@ $(LIBS) $^ + + +# ---------- Default rule + +%.$(ObjSuf): %.cpp + @echo "Compiling source $@..." + $(CXX) $(CXXFLAGS) -c $< + + +#----------- do the dictionary +TSlsDetectorDict.$(SrcSuf): $(HEADERS) + @echo "Generating dictionary $@..." + rootcint -f $@ -c -p $^ + +#------------------------------------------------------------------------------- +all: $(SLSDETSO) + +clean: + @rm -f $(SLSDETO) core + +distclean: clean + @rm -f *Dict.* *.so *.o + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/Makefile.arch b/slsDetectorSoftware/slsDetectorAnalysis/Makefile.arch new file mode 100644 index 000000000..707a4e35b --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/Makefile.arch @@ -0,0 +1,575 @@ +# -*- mode: makefile -*- +# +# Makefile containing platform dependencies for ROOT based projects. +# +# Copyright (c) 2000 Rene Brun and Fons Rademakers +# +# Author: Fons Rademakers, 29/2/2000 + +ROOTCONFIG := root-config + +ARCH := $(shell $(ROOTCONFIG) --arch) +PLATFORM := $(shell $(ROOTCONFIG) --platform) +ALTCC := $(shell $(ROOTCONFIG) --cc) +ALTCXX := $(shell $(ROOTCONFIG) --cxx) +ALTF77 := $(shell $(ROOTCONFIG) --f77) +ALTLD := $(shell $(ROOTCONFIG) --ld) + +#CXX = +ObjSuf = o +SrcSuf = cpp +ExeSuf = +DllSuf = so +OutPutOpt = -o # keep whitespace after "-o" + +ifeq (debug,$(findstring debug,$(ROOTBUILD))) +OPT = -g +OPT2 = -g +else +ifneq ($(findstring debug, $(strip $(shell $(ROOTCONFIG) --config))),) +OPT = -g +OPT2 = -g +else +OPT = -O +OPT2 = -O2 +endif +endif + +ROOTCFLAGS := $(shell $(ROOTCONFIG) --cflags) +ROOTLDFLAGS := $(shell $(ROOTCONFIG) --ldflags) +ROOTLIBS := $(shell $(ROOTCONFIG) --libs) +ROOTGLIBS := $(shell $(ROOTCONFIG) --glibs) +HASTHREAD := $(shell $(ROOTCONFIG) --has-thread) +ROOTDICTTYPE := $(shell $(ROOTCONFIG) --dicttype) +NOSTUBS := $(shell $(ROOTCONFIG) --nostubs) +ROOTCINT := rootcint + +# Stub Functions Generation +ifeq ($(NOSTUBS),yes) + ROOTCINT = export CXXFLAGS="$(CXXFLAGS)"; $(ROOTSYS)/core/utils/src/rootcint_nostubs.sh -$(ROOTDICTTYPE) +endif + +ifeq ($(ARCH),hpuxacc) +# HP-UX 10.x with aCC +CXX = aCC +CXXFLAGS = $(OPT) +Z +LD = aCC +LDFLAGS = $(OPT) -z +SOFLAGS = -b +endif + +ifeq ($(ARCH),hpuxia64acc) +# HP-UX 11i 1.5 (IA-64) with aCC +CXX = aCC +CXXFLAGS = +DD64 $(OPT) +Z +LD = aCC +LDFLAGS = +DD64 $(OPT) -z +SOFLAGS = -b +endif + +ifeq ($(ARCH),hpuxgcc) +# HP-UX 10.x with g++ +CXXFLAGS = $(OPT) -fPIC +CXX = g++ +LD = g++ +LDFLAGS = $(OPT) +SOFLAGS = -fPIC -shared +endif + +ifeq ($(ARCH),hurddeb) +# GNU/Hurd +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),aix) +# IBM AIX xlC 4.x +CXX = xlC +CXXFLAGS = $(OPT) +LD = xlC +LDFLAGS = $(OPT) +SOFLAGS = +DllSuf = a +endif + +ifeq ($(ARCH),aix5) +# IBM AIX xlC 5.x +CXX = xlC +CXXFLAGS = $(OPT) +LD = xlC +LDFLAGS = $(OPT) +SOFLAGS = +DllSuf = a +endif + +ifeq ($(ARCH),aixgcc) +# IBM AIX with GCC +CXX = g++ +CXXFLAGS = $(OPT) +LD = g++ +LDFLAGS = $(OPT) +SOFLAGS = -shared +DllSuf = a +EXPLLINKLIBS = $(ROOTLIBS) $(ROOTGLIBS) +endif + +ifeq ($(ARCH),solaris) +# Solaris CC +CXX = /opt/SUNWspro/bin/CC +CXXFLAGS = $(OPT) -KPIC +LD = /opt/SUNWspro/bin/CC +LDFLAGS = $(OPT) +SOFLAGS = -G +endif + +ifeq ($(ARCH),solarisCC5) +# Solaris CC 5.0 +CXX = CC +CXXFLAGS = $(OPT) -KPIC +LD = CC +LDFLAGS = $(OPT) +SOFLAGS = -G +endif + +ifeq ($(ARCH),solarisgcc) +# Solaris gcc +CXX = g++ +CXXFLAGS = $(OPT) -fPIC +LD = g++ +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),solariskcc) +# Solaris kcc +CXX = KCC --one_instantiation_per_object +CXXFLAGS = -O4 -KPIC +LD = KCC +LDFLAGS = -O4 +SOFLAGS = +endif + +ifeq ($(ARCH),solarisx86) +# Solaris CC on Intel +CXX = CC +CXXFLAGS = $(OPT) -KPIC +LD = CC +LDFLAGS = $(OPT) +SOFLAGS = -G +endif + +ifeq ($(ARCH),sgicc) +# SGI +CXX = CC -n32 -I/usr/include/CC.sgi +CXXFLAGS = $(OPT) +LD = CC -n32 -LANG:std -I/usr/include/CC.sgi +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),sgicc64) +# SGI +CXX = CC -64 -I/usr/include/CC.sgi +CXXFLAGS = $(OPT) +LD = CC -64 -LANG:std -I/usr/include/CC.sgi +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),sgigcc) +# SGI 6.x with gcc +CXX = g++ +CXXFLAGS = $(OPT) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT) -Wl,-u,__builtin_new -Wl,-u,__builtin_delete -Wl,-u,__nw__FUiPv +SOFLAGS = -shared +endif + +ifeq ($(ARCH),sgin32gcc) +# SGI 6.x with gcc for n32 ABI +CXX = g++ +CXXFLAGS = $(OPT) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT) -L/usr/lib32 -Wl,-woff,134 -lgen +SOFLAGS = -shared +endif + +ifeq ($(ARCH),sgikcc) +# SGI with KCC +CXX = KCC -n32 --one_instantiation_per_object +CXXFLAGS = $(OPT) +LD = KCC -n32 +LDFLAGS = $(OPT) +SOFLAGS = +endif + +ifeq ($(ARCH),alphagcc) +# Alpha/OSF with gcc +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -Wl,-expect_unresolved,* -shared +endif + +ifeq ($(ARCH),alphakcc) +# Alpha/OSF with kai compiler (not yet valid) +CXX = KCC --one_instantiation_per_object +CXXFLAGS = $(OPT) -fPIC +LD = KCC +LDFLAGS = $(OPT) +SOFLAGS = -Wl,-expect_unresolved,* -shared +endif + +ifeq ($(ARCH),alphacxx6) +# Alpha/OSF with cxx6 +CXX = cxx +CXXFLAGS = $(OPT) +LD = cxx +LDFLAGS = $(OPT) +SOFLAGS = -shared -nocxxstd -Wl,-expect_unresolved,*,-msym +endif + +ifeq ($(ARCH),linuxdeb2ppc) +# Debian/Linux on the PowerPC +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linux) +# Linux with egcs, gcc 2.9x, gcc 3.x +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxkcc) +# Linux with the KAI compiler +CXX = KCC --one_instantiation_per_object +CXXFLAGS = $(OPT) -fPIC +K0 +LD = KCC +LDFLAGS = $(OPT) $(shell $(ROOTCONFIG) --cflags) +SOFLAGS = +endif + +ifeq ($(ARCH),linuxicc) +# Linux with Intel icc compiler +ICC_MAJOR := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \ + cut -d'.' -f1) +ICC_MINOR := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \ + cut -d'.' -f2) +CXX = icc +CXXFLAGS = $(OPT) -fPIC -wd1476 +LD = icpc +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxppcgcc) +# PPC Linux with gcc and glibc +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxia64gcc) +# Itanium Linux with gcc 2.9x +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxia64sgi) +# Itanium Linux with sgiCC +CXX = sgiCC +CXXFLAGS = $(OPT) -Wall -fPIC +LD = gsgiCC +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxia64ecc) +# Itanium Linux with Intel icc (was ecc) +ICC_MAJOR := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \ + cut -d'.' -f1) +ICC_MINOR := $(shell icc -v 2>&1 | awk '{ if (NR==1) print $$2 }' | \ + cut -d'.' -f2) +CXX = icc +CXXFLAGS = $(OPT) -fPIC -wd1476 -ftz +LD = icpc +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxx8664gcc) +# AMD Opteron and Intel EM64T (64 bit mode) Linux with gcc 3.x +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxppc64gcc) +# PPC64 Linux with gcc 3.x +CXX = g++ +CXXFLAGS = $(OPT) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxx8664icc) +# AMD Opteron and Intel EM64T (64 bit mode) Linux with Intel icc compiler +CXX = icc +CXXFLAGS = $(OPT) -fPIC -wd1476 -wd1572 +LD = icpc +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxalphagcc) +# Alpha Linux with gcc +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxmips) +# GNU/Linux on mips (BE/LE, O32/N32/N64) with gcc +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxhppa) +# GNU/Linux on hppa with gcc +CXX = g++ +CXXFLAGS = $(OPT2) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT2) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),linuxarm) +# ARM Linux with egcs +CXX = g++ +CXXFLAGS = $(OPT) -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT) +SOFLAGS = -shared +endif + +ifeq ($(ARCH),freebsd4) +# FreeBSD with glibc +CXX = g++ +CXXFLAGS = $(OPT) -W -Wall -fPIC +LD = $(CXX) +LDFLAGS = $(OPT) +SOFLAGS = -shared -Wl,-x +endif + +ifeq ($(ARCH),freebsd5) +# FreeBSD with glibc +CXX = g++ +CXXFLAGS = $(OPT) -W -Wall -fPIC +LD = $(CXX) +LDFLAGS = $(OPT) +SOFLAGS = -shared -Wl,-x +endif + +ifeq ($(ARCH),freebsd7) +# FreeBSD with libc +CXX = g++ +CXXFLAGS = $(OPT) -W -Wall -fPIC +LD = $(CXX) +LDFLAGS = $(OPT) +SOFLAGS = -shared -Wl,-x +endif + +ifeq ($(ARCH),openbsd) +# OpenBSD with libc +CXX = g++ +CXXFLAGS = $(OPT) -pipe -W -Wall -fPIC +LD = g++ +LDFLAGS = $(OPT) +SOFLAGS = -shared -Wl,-x +endif + +ifeq ($(ARCH),macosx) +# MacOS X with cc (GNU cc 2.95.2 and gcc 3.3) +MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2) +MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR) +CXX = g++ +CXXFLAGS = $(OPT2) -pipe -Wall -W -Woverloaded-virtual +LD = $(MACOSXTARGET) g++ +LDFLAGS = $(OPT2) +# The SOFLAGS will be used to create the .dylib, +# the .so will be created separately +ifeq ($(subst $(MACOSX_MINOR),,1234),1234) +DllSuf = so +else +DllSuf = dylib +endif +UNDEFOPT = dynamic_lookup +ifneq ($(subst $(MACOSX_MINOR),,12),12) +UNDEFOPT = suppress +LD = g++ +endif +SOFLAGS = -dynamiclib -single_module -undefined $(UNDEFOPT) -install_name $(CURDIR)/ +endif + +ifeq ($(ARCH),macosxicc) +# MacOS X with Intel icc compiler +MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2) +MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR) +ifeq ($(MACOSX_MINOR),5) +MACOSX_MINOR := 4 +endif +CXX = icc +CXXFLAGS = $(OPT) -fPIC -wd1476 +LD = $(MACOSXTARGET) icpc +LDFLAGS = $(OPT) +# The SOFLAGS will be used to create the .dylib, +# the .so will be created separately +ifeq ($(subst $(MACOSX_MINOR),,1234),1234) +DllSuf = so +else +DllSuf = dylib +endif +SOFLAGS = -dynamiclib -single_module -undefined dynamic_lookup -install_name $(CURDIR)/ +endif + +ifeq ($(ARCH),macosx64) +# MacOS X >= 10.4 with gcc 64 bit mode (GNU gcc 4.*) +# Only specific option (-m64) comes from root-config +MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2) +MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR) +CXX = g++ +CXXFLAGS = $(OPT2) -pipe -Wall -W -Woverloaded-virtual +LD = $(MACOSXTARGET) g++ +LDFLAGS = $(OPT2) +# The SOFLAGS will be used to create the .dylib, +# the .so will be created separately +ifeq ($(subst $(MACOSX_MINOR),,1234),1234) +DllSuf = so +else +DllSuf = dylib +endif +SOFLAGS = -dynamiclib -single_module -undefined dynamic_lookup -install_name $(CURDIR)/ +endif + +ifeq ($(ARCH),macosxxlc) +# MacOS X with IBM xlC compiler +MACOSX_MINOR := $(shell sw_vers | sed -n 's/ProductVersion://p' | cut -d . -f 2) +MACOSXTARGET := MACOSX_DEPLOYMENT_TARGET=10.$(MACOSX_MINOR) +CXX = xlC +CXXFLAGS = $(OPT) +LD = $(MACOSXTARGET) xlC +LDFLAGS = $(OPT) -Wl,-bind_at_load +# The SOFLAGS will be used to create the .dylib, +# the .so will be created separately +DllSuf = dylib +UNDEFOPT = dynamic_lookup +ifneq ($(subst $(MACOSX_MINOR),,12),12) +UNDEFOPT = suppress +LD = xlC +endif +SOFLAGS = -qmkshrobj -single_module -undefined $(UNDEFOPT) -install_name $(CURDIR)/ +endif + +ifeq ($(ARCH),win32) +# Windows with the VC++ compiler +VC_MAJOR := $(shell unset VS_UNICODE_OUTPUT; cl.exe 2>&1 | awk '{ if (NR==1) print $$8 }' | \ + cut -d'.' -f1) +ObjSuf = obj +SrcSuf = cxx +ExeSuf = .exe +DllSuf = dll +OutPutOpt = -out: +CXX = cl +ifeq (debug,$(findstring debug,$(ROOTBUILD))) +CXXOPT = -Z7 +LDOPT = -debug +else +ifneq ($(findstring debug, $(strip $(shell $(ROOTCONFIG) --config))),) +CXXOPT = -Z7 +LDOPT = -debug +else +CXXOPT = -O2 +LDOPT = -opt:ref +endif +endif +ROOTINCDIR := -I$(shell cygpath -m `$(ROOTCONFIG) --incdir`) +CXXFLAGS = $(CXXOPT) -nologo $(ROOTINCDIR) -FIw32pragma.h +LD = link +LDFLAGS = $(LDOPT) -nologo +SOFLAGS = -DLL + +EXPLLINKLIBS = $(ROOTLIBS) $(ROOTGLIBS) +ifneq (,$(findstring $(VC_MAJOR),14 15)) +MT_EXE = mt -nologo -manifest $@.manifest -outputresource:$@\;1; rm -f $@.manifest +MT_DLL = mt -nologo -manifest $@.manifest -outputresource:$@\;2; rm -f $@.manifest +else +MT_EXE = +MT_DLL = +endif +endif + +ifeq ($(ARCH),win32gcc) +# Windows with gcc +DllSuf = dll +ExeSuf = .exe +CXX = g++ +CXXFLAGS = $(OPT) -pipe -Wall -Woverloaded-virtual -I/usr/X11R6/include +LD = g++ +LDFLAGS = $(OPT) -Wl,--enable-auto-import \ + -Wl,--enable-runtime-pseudo-reloc \ + -L/usr/X11R6/lib +SOFLAGS = -shared -Wl,--enable-auto-image-base \ + -Wl,--export-all-symbols +EXPLLINKLIBS = $(ROOTLIBS) $(ROOTGLIBS) +endif + +ifeq ($(CXX),) +$(error $(ARCH) invalid architecture) +endif + +CXXFLAGS += $(ROOTCFLAGS) +LDFLAGS += $(ROOTLDFLAGS) +LIBS = $(ROOTLIBS) $(SYSLIBS) +GLIBS = $(ROOTGLIBS) $(SYSLIBS) + +ifneq ($(ALTCC),) + CC = $(ALTCC) +endif +ifneq ($(ALTCXX),) + CXX = $(ALTCXX) +endif +ifneq ($(ALTF77),) + F77 = $(ALTF77) +endif +ifneq ($(ALTLD),) + LD = $(ALTLD) +endif + +ifneq ($(findstring g++, $(CXX)),) +GCC_MAJOR := $(shell $(CXX) -dumpversion 2>&1 | cut -d'.' -f1) +GCC_MINOR := $(shell $(CXX) -dumpversion 2>&1 | cut -d'.' -f2) +endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/TSlsDetectorDict.cpp b/slsDetectorSoftware/slsDetectorAnalysis/TSlsDetectorDict.cpp new file mode 100644 index 000000000..67c907790 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/TSlsDetectorDict.cpp @@ -0,0 +1,691 @@ +// +// File generated by rootcint at Thu Mar 29 16:09:00 2012 + +// Do NOT change. Changes will be lost next time file is generated +// + +#include "RConfig.h" //rootcint 4834 +#if !defined(R__ACCESS_IN_SYMBOL) +//Break the privacy of classes -- Disabled for the moment +#define private public +#define protected public +#endif + +// Since CINT ignores the std namespace, we need to do so in this file. +namespace std {} using namespace std; +#include "TSlsDetectorDict.h" + +#include "TClass.h" +#include "TBuffer.h" +#include "TMemberInspector.h" +#include "TError.h" + +#ifndef G__ROOT +#define G__ROOT +#endif + +#include "RtypesImp.h" +#include "TIsAProxy.h" + +// START OF SHADOWS + +namespace ROOT { + namespace Shadow { + } // of namespace Shadow +} // of namespace ROOT +// END OF SHADOWS + +namespace ROOT { + void energyCalibration_ShowMembers(void *obj, TMemberInspector &R__insp, char *R__parent); + static void energyCalibration_Dictionary(); + static void *new_energyCalibration(void *p = 0); + static void *newArray_energyCalibration(Long_t size, void *p); + static void delete_energyCalibration(void *p); + static void deleteArray_energyCalibration(void *p); + static void destruct_energyCalibration(void *p); + + // Function generating the singleton type initializer + static TGenericClassInfo *GenerateInitInstanceLocal(const ::energyCalibration*) + { + ::energyCalibration *ptr = 0; + static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(::energyCalibration),0); + static ::ROOT::TGenericClassInfo + instance("energyCalibration", "./energyCalibration.h", 168, + typeid(::energyCalibration), DefineBehavior(ptr, ptr), + 0, &energyCalibration_Dictionary, isa_proxy, 0, + sizeof(::energyCalibration) ); + instance.SetNew(&new_energyCalibration); + instance.SetNewArray(&newArray_energyCalibration); + instance.SetDelete(&delete_energyCalibration); + instance.SetDeleteArray(&deleteArray_energyCalibration); + instance.SetDestructor(&destruct_energyCalibration); + return &instance; + } + TGenericClassInfo *GenerateInitInstance(const ::energyCalibration*) + { + return GenerateInitInstanceLocal((::energyCalibration*)0); + } + // Static variable to force the class initialization + static ::ROOT::TGenericClassInfo *_R__UNIQUE_(Init) = GenerateInitInstanceLocal((const ::energyCalibration*)0x0); R__UseDummy(_R__UNIQUE_(Init)); + + // Dictionary for non-ClassDef classes + static void energyCalibration_Dictionary() { + ::ROOT::GenerateInitInstanceLocal((const ::energyCalibration*)0x0)->GetClass(); + } + +} // end of namespace ROOT + +namespace ROOT { + void angularCalibration_ShowMembers(void *obj, TMemberInspector &R__insp, char *R__parent); + static void angularCalibration_Dictionary(); + static void *new_angularCalibration(void *p = 0); + static void *newArray_angularCalibration(Long_t size, void *p); + static void delete_angularCalibration(void *p); + static void deleteArray_angularCalibration(void *p); + static void destruct_angularCalibration(void *p); + + // Function generating the singleton type initializer + static TGenericClassInfo *GenerateInitInstanceLocal(const ::angularCalibration*) + { + ::angularCalibration *ptr = 0; + static ::TVirtualIsAProxy* isa_proxy = new ::TIsAProxy(typeid(::angularCalibration),0); + static ::ROOT::TGenericClassInfo + instance("angularCalibration", "./angularCalibration.h", 35, + typeid(::angularCalibration), DefineBehavior(ptr, ptr), + 0, &angularCalibration_Dictionary, isa_proxy, 0, + sizeof(::angularCalibration) ); + instance.SetNew(&new_angularCalibration); + instance.SetNewArray(&newArray_angularCalibration); + instance.SetDelete(&delete_angularCalibration); + instance.SetDeleteArray(&deleteArray_angularCalibration); + instance.SetDestructor(&destruct_angularCalibration); + return &instance; + } + TGenericClassInfo *GenerateInitInstance(const ::angularCalibration*) + { + return GenerateInitInstanceLocal((::angularCalibration*)0); + } + // Static variable to force the class initialization + static ::ROOT::TGenericClassInfo *_R__UNIQUE_(Init) = GenerateInitInstanceLocal((const ::angularCalibration*)0x0); R__UseDummy(_R__UNIQUE_(Init)); + + // Dictionary for non-ClassDef classes + static void angularCalibration_Dictionary() { + ::ROOT::GenerateInitInstanceLocal((const ::angularCalibration*)0x0)->GetClass(); + } + +} // end of namespace ROOT + +namespace ROOT { + // Wrappers around operator new + static void *new_energyCalibration(void *p) { + return p ? ::new((::ROOT::TOperatorNewHelper*)p) ::energyCalibration : new ::energyCalibration; + } + static void *newArray_energyCalibration(Long_t nElements, void *p) { + return p ? ::new((::ROOT::TOperatorNewHelper*)p) ::energyCalibration[nElements] : new ::energyCalibration[nElements]; + } + // Wrapper around operator delete + static void delete_energyCalibration(void *p) { + delete ((::energyCalibration*)p); + } + static void deleteArray_energyCalibration(void *p) { + delete [] ((::energyCalibration*)p); + } + static void destruct_energyCalibration(void *p) { + typedef ::energyCalibration current_t; + ((current_t*)p)->~current_t(); + } +} // end of namespace ROOT for class ::energyCalibration + +namespace ROOT { + // Wrappers around operator new + static void *new_angularCalibration(void *p) { + return p ? ::new((::ROOT::TOperatorNewHelper*)p) ::angularCalibration : new ::angularCalibration; + } + static void *newArray_angularCalibration(Long_t nElements, void *p) { + return p ? ::new((::ROOT::TOperatorNewHelper*)p) ::angularCalibration[nElements] : new ::angularCalibration[nElements]; + } + // Wrapper around operator delete + static void delete_angularCalibration(void *p) { + delete ((::angularCalibration*)p); + } + static void deleteArray_angularCalibration(void *p) { + delete [] ((::angularCalibration*)p); + } + static void destruct_angularCalibration(void *p) { + typedef ::angularCalibration current_t; + ((current_t*)p)->~current_t(); + } +} // end of namespace ROOT for class ::angularCalibration + +/******************************************************** +* TSlsDetectorDict.cpp +* CAUTION: DON'T CHANGE THIS FILE. THIS FILE IS AUTOMATICALLY GENERATED +* FROM HEADER FILES LISTED IN G__setup_cpp_environmentXXX(). +* CHANGE THOSE HEADER FILES AND REGENERATE THIS FILE. +********************************************************/ + +#ifdef G__MEMTEST +#undef malloc +#undef free +#endif + +#if defined(__GNUC__) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 1) +#pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif + +extern "C" void G__cpp_reset_tagtableTSlsDetectorDict(); + +extern "C" void G__set_cpp_environmentTSlsDetectorDict() { + G__add_compiledheader("TObject.h"); + G__add_compiledheader("TMemberInspector.h"); + G__add_compiledheader("energyCalibration.h"); + G__add_compiledheader("angularCalibration.h"); + G__cpp_reset_tagtableTSlsDetectorDict(); +} +#include +extern "C" int G__cpp_dllrevTSlsDetectorDict() { return(30051515); } + +/********************************************************* +* Member function Interface Method +*********************************************************/ + +/* energyCalibration */ +static int G__TSlsDetectorDict_85_0_1(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + energyCalibration* p = NULL; + char* gvp = (char*) G__getgvp(); + int n = G__getaryconstruct(); + if (n) { + if ((gvp == (char*)G__PVOID) || (gvp == 0)) { + p = new energyCalibration[n]; + } else { + p = new((void*) gvp) energyCalibration[n]; + } + } else { + if ((gvp == (char*)G__PVOID) || (gvp == 0)) { + p = new energyCalibration; + } else { + p = new((void*) gvp) energyCalibration; + } + } + result7->obj.i = (long) p; + result7->ref = (long) p; + result7->type = 'u'; + result7->tagnum = G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration); + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_85_0_2(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + switch (libp->paran) { + case 1: + G__letint(result7, 105, (long) ((energyCalibration*) G__getstructoffset())->setPlotFlag((int) G__int(libp->para[0]))); + break; + case 0: + G__letint(result7, 105, (long) ((energyCalibration*) G__getstructoffset())->setPlotFlag()); + break; + } + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_85_0_3(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + switch (libp->paran) { + case 1: + G__letint(result7, 105, (long) ((energyCalibration*) G__getstructoffset())->setScanSign((int) G__int(libp->para[0]))); + break; + case 0: + G__letint(result7, 105, (long) ((energyCalibration*) G__getstructoffset())->setScanSign()); + break; + } + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_85_0_4(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + switch (libp->paran) { + case 1: + G__letint(result7, 105, (long) ((energyCalibration*) G__getstructoffset())->setChargeSharing((int) G__int(libp->para[0]))); + break; + case 0: + G__letint(result7, 105, (long) ((energyCalibration*) G__getstructoffset())->setChargeSharing()); + break; + } + return(1 || funcname || hash || result7 || libp) ; +} + +// automatic copy constructor +static int G__TSlsDetectorDict_85_0_5(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) + +{ + energyCalibration* p; + void* tmp = (void*) G__int(libp->para[0]); + p = new energyCalibration(*(energyCalibration*) tmp); + result7->obj.i = (long) p; + result7->ref = (long) p; + result7->type = 'u'; + result7->tagnum = G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration); + return(1 || funcname || hash || result7 || libp) ; +} + +// automatic destructor +typedef energyCalibration G__TenergyCalibration; +static int G__TSlsDetectorDict_85_0_6(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + char* gvp = (char*) G__getgvp(); + long soff = G__getstructoffset(); + int n = G__getaryconstruct(); + // + //has_a_delete: 0 + //has_own_delete1arg: 0 + //has_own_delete2arg: 0 + // + if (!soff) { + return(1); + } + if (n) { + if (gvp == (char*)G__PVOID) { + delete[] (energyCalibration*) soff; + } else { + G__setgvp((long) G__PVOID); + for (int i = n - 1; i >= 0; --i) { + ((energyCalibration*) (soff+(sizeof(energyCalibration)*i)))->~G__TenergyCalibration(); + } + G__setgvp((long)gvp); + } + } else { + if (gvp == (char*)G__PVOID) { + delete (energyCalibration*) soff; + } else { + G__setgvp((long) G__PVOID); + ((energyCalibration*) (soff))->~G__TenergyCalibration(); + G__setgvp((long)gvp); + } + } + G__setnull(result7); + return(1 || funcname || hash || result7 || libp) ; +} + +// automatic assignment operator +static int G__TSlsDetectorDict_85_0_7(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + energyCalibration* dest = (energyCalibration*) G__getstructoffset(); + *dest = *(energyCalibration*) libp->para[0].ref; + const energyCalibration& obj = *dest; + result7->ref = (long) (&obj); + result7->obj.i = (long) (&obj); + return(1 || funcname || hash || result7 || libp) ; +} + + +/* angularCalibration */ +static int G__TSlsDetectorDict_87_0_1(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + angularCalibration* p = NULL; + char* gvp = (char*) G__getgvp(); + int n = G__getaryconstruct(); + if (n) { + if ((gvp == (char*)G__PVOID) || (gvp == 0)) { + p = new angularCalibration[n]; + } else { + p = new((void*) gvp) angularCalibration[n]; + } + } else { + if ((gvp == (char*)G__PVOID) || (gvp == 0)) { + p = new angularCalibration; + } else { + p = new((void*) gvp) angularCalibration; + } + } + result7->obj.i = (long) p; + result7->ref = (long) p; + result7->type = 'u'; + result7->tagnum = G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration); + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_87_0_2(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + switch (libp->paran) { + case 1: + G__letint(result7, 105, (long) ((angularCalibration*) G__getstructoffset())->setDirection((int) G__int(libp->para[0]))); + break; + case 0: + G__letint(result7, 105, (long) ((angularCalibration*) G__getstructoffset())->setDirection()); + break; + } + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_87_0_3(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + G__letdouble(result7, 102, (double) ((angularCalibration*) G__getstructoffset())->setEncoder((double) G__double(libp->para[0]))); + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_87_0_4(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + G__letdouble(result7, 102, (double) ((angularCalibration*) G__getstructoffset())->getEncoder()); + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_87_0_5(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + G__letdouble(result7, 102, (double) ((angularCalibration*) G__getstructoffset())->setTotalOffset((double) G__double(libp->para[0]))); + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_87_0_6(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + G__letdouble(result7, 102, (double) ((angularCalibration*) G__getstructoffset())->getTotalOffset()); + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_87_0_7(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + ((angularCalibration*) G__getstructoffset())->setAngularRange((double) G__double(libp->para[0]), (double) G__double(libp->para[1])); + G__setnull(result7); + return(1 || funcname || hash || result7 || libp) ; +} + +static int G__TSlsDetectorDict_87_0_8(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + ((angularCalibration*) G__getstructoffset())->getAngularRange(*(double*) G__doubleref(&libp->para[0]), *(double*) G__doubleref(&libp->para[1])); + G__setnull(result7); + return(1 || funcname || hash || result7 || libp) ; +} + +// automatic copy constructor +static int G__TSlsDetectorDict_87_0_9(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) + +{ + angularCalibration* p; + void* tmp = (void*) G__int(libp->para[0]); + p = new angularCalibration(*(angularCalibration*) tmp); + result7->obj.i = (long) p; + result7->ref = (long) p; + result7->type = 'u'; + result7->tagnum = G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration); + return(1 || funcname || hash || result7 || libp) ; +} + +// automatic destructor +typedef angularCalibration G__TangularCalibration; +static int G__TSlsDetectorDict_87_0_10(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + char* gvp = (char*) G__getgvp(); + long soff = G__getstructoffset(); + int n = G__getaryconstruct(); + // + //has_a_delete: 0 + //has_own_delete1arg: 0 + //has_own_delete2arg: 0 + // + if (!soff) { + return(1); + } + if (n) { + if (gvp == (char*)G__PVOID) { + delete[] (angularCalibration*) soff; + } else { + G__setgvp((long) G__PVOID); + for (int i = n - 1; i >= 0; --i) { + ((angularCalibration*) (soff+(sizeof(angularCalibration)*i)))->~G__TangularCalibration(); + } + G__setgvp((long)gvp); + } + } else { + if (gvp == (char*)G__PVOID) { + delete (angularCalibration*) soff; + } else { + G__setgvp((long) G__PVOID); + ((angularCalibration*) (soff))->~G__TangularCalibration(); + G__setgvp((long)gvp); + } + } + G__setnull(result7); + return(1 || funcname || hash || result7 || libp) ; +} + +// automatic assignment operator +static int G__TSlsDetectorDict_87_0_11(G__value* result7, G__CONST char* funcname, struct G__param* libp, int hash) +{ + angularCalibration* dest = (angularCalibration*) G__getstructoffset(); + *dest = *(angularCalibration*) libp->para[0].ref; + const angularCalibration& obj = *dest; + result7->ref = (long) (&obj); + result7->obj.i = (long) (&obj); + return(1 || funcname || hash || result7 || libp) ; +} + + +/* Setting up global function */ + +/********************************************************* +* Member function Stub +*********************************************************/ + +/* energyCalibration */ + +/* angularCalibration */ + +/********************************************************* +* Global function Stub +*********************************************************/ + +/********************************************************* +* Get size of pointer to member function +*********************************************************/ +class G__Sizep2memfuncTSlsDetectorDict { + public: + G__Sizep2memfuncTSlsDetectorDict(): p(&G__Sizep2memfuncTSlsDetectorDict::sizep2memfunc) {} + size_t sizep2memfunc() { return(sizeof(p)); } + private: + size_t (G__Sizep2memfuncTSlsDetectorDict::*p)(); +}; + +size_t G__get_sizep2memfuncTSlsDetectorDict() +{ + G__Sizep2memfuncTSlsDetectorDict a; + G__setsizep2memfunc((int)a.sizep2memfunc()); + return((size_t)a.sizep2memfunc()); +} + + +/********************************************************* +* virtual base class offset calculation interface +*********************************************************/ + + /* Setting up class inheritance */ + +/********************************************************* +* Inheritance information setup/ +*********************************************************/ +extern "C" void G__cpp_setup_inheritanceTSlsDetectorDict() { + + /* Setting up class inheritance */ +} + +/********************************************************* +* typedef information setup/ +*********************************************************/ +extern "C" void G__cpp_setup_typetableTSlsDetectorDict() { + + /* Setting up typedef entry */ +} + +/********************************************************* +* Data Member information setup/ +*********************************************************/ + + /* Setting up class,struct,union tag member variable */ + + /* energyCalibration */ +static void G__setup_memvarenergyCalibration(void) { + G__tag_memvar_setup(G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration)); + { energyCalibration *p; p=(energyCalibration*)0x1000; if (p) { } + G__memvar_setup((void*)0,85,0,0,G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibrationFunctions),-1,-1,4,"funcs=",0,(char*)NULL); + G__memvar_setup((void*)0,105,0,0,-1,-1,-1,4,"plot_flag=",0,"*< 0 does not plot, >0 plots (flags?) */"); + G__memvar_setup((void*)0,105,0,0,-1,-1,-1,4,"cs_flag=",0,"*< 0 functions without charge sharing contribution, >0 with charge sharing contribution */"); + } + G__tag_memvar_reset(); +} + + + /* angularCalibration */ +static void G__setup_memvarangularCalibration(void) { + G__tag_memvar_setup(G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration)); + { angularCalibration *p; p=(angularCalibration*)0x1000; if (p) { } + G__memvar_setup((void*)0,105,0,0,-1,-1,-1,4,"direction=",0,"*< angulat direction of the detector -can be +1 or -1 */"); + G__memvar_setup((void*)0,102,0,0,-1,-1,-1,4,"encoder=",0,"*< position of the detector encoder */"); + G__memvar_setup((void*)0,102,0,0,-1,-1,-1,4,"totalOffset=",0,"*< total offset of the detector */"); + G__memvar_setup((void*)0,102,0,0,-1,-1,-1,4,"ang_min=",0,"*< minimum of the angular range for peak fitting*/"); + G__memvar_setup((void*)0,102,0,0,-1,-1,-1,4,"ang_max=",0,"*< maximum of the angular range for peak fitting */"); + } + G__tag_memvar_reset(); +} + +extern "C" void G__cpp_setup_memvarTSlsDetectorDict() { +} +/*********************************************************** +************************************************************ +************************************************************ +************************************************************ +************************************************************ +************************************************************ +************************************************************ +***********************************************************/ + +/********************************************************* +* Member function information setup for each class +*********************************************************/ +static void G__setup_memfuncenergyCalibration(void) { + /* energyCalibration */ + G__tag_memfunc_setup(G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration)); + G__memfunc_setup("energyCalibration",1778,G__TSlsDetectorDict_85_0_1, 105, G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration), -1, 0, 0, 1, 1, 0, "", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("setPlotFlag",1125,G__TSlsDetectorDict_85_0_2, 105, -1, -1, 0, 1, 1, 1, 0, "i - - 0 '-1' p", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("setScanSign",1122,G__TSlsDetectorDict_85_0_3, 105, -1, -1, 0, 1, 1, 1, 0, "i - - 0 '0' s", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("setChargeSharing",1634,G__TSlsDetectorDict_85_0_4, 105, -1, -1, 0, 1, 1, 1, 0, "i - - 0 '-1' p", (char*)NULL, (void*) NULL, 0); + // automatic copy constructor + G__memfunc_setup("energyCalibration", 1778, G__TSlsDetectorDict_85_0_5, (int) ('i'), G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration), -1, 0, 1, 1, 1, 0, "u 'energyCalibration' - 11 - -", (char*) NULL, (void*) NULL, 0); + // automatic destructor + G__memfunc_setup("~energyCalibration", 1904, G__TSlsDetectorDict_85_0_6, (int) ('y'), -1, -1, 0, 0, 1, 1, 0, "", (char*) NULL, (void*) NULL, 0); + // automatic assignment operator + G__memfunc_setup("operator=", 937, G__TSlsDetectorDict_85_0_7, (int) ('u'), G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration), -1, 1, 1, 1, 1, 0, "u 'energyCalibration' - 11 - -", (char*) NULL, (void*) NULL, 0); + G__tag_memfunc_reset(); +} + +static void G__setup_memfuncangularCalibration(void) { + /* angularCalibration */ + G__tag_memfunc_setup(G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration)); + G__memfunc_setup("angularCalibration",1874,G__TSlsDetectorDict_87_0_1, 105, G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration), -1, 0, 0, 1, 1, 0, "", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("setDirection",1261,G__TSlsDetectorDict_87_0_2, 105, -1, -1, 0, 1, 1, 1, 0, "i - - 0 '0' d", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("setEncoder",1036,G__TSlsDetectorDict_87_0_3, 102, -1, -1, 0, 1, 1, 1, 0, "f - - 0 - f", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("getEncoder",1024,G__TSlsDetectorDict_87_0_4, 102, -1, -1, 0, 0, 1, 1, 0, "", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("setTotalOffset",1463,G__TSlsDetectorDict_87_0_5, 102, -1, -1, 0, 1, 1, 1, 0, "f - - 0 - f", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("getTotalOffset",1451,G__TSlsDetectorDict_87_0_6, 102, -1, -1, 0, 0, 1, 1, 0, "", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("setAngularRange",1539,G__TSlsDetectorDict_87_0_7, 121, -1, -1, 0, 2, 1, 1, 0, +"f - - 0 - mi f - - 0 - ma", (char*)NULL, (void*) NULL, 0); + G__memfunc_setup("getAngularRange",1527,G__TSlsDetectorDict_87_0_8, 121, -1, -1, 0, 2, 1, 1, 0, +"f - - 1 - mi f - - 1 - ma", (char*)NULL, (void*) NULL, 0); + // automatic copy constructor + G__memfunc_setup("angularCalibration", 1874, G__TSlsDetectorDict_87_0_9, (int) ('i'), G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration), -1, 0, 1, 1, 1, 0, "u 'angularCalibration' - 11 - -", (char*) NULL, (void*) NULL, 0); + // automatic destructor + G__memfunc_setup("~angularCalibration", 2000, G__TSlsDetectorDict_87_0_10, (int) ('y'), -1, -1, 0, 0, 1, 1, 0, "", (char*) NULL, (void*) NULL, 0); + // automatic assignment operator + G__memfunc_setup("operator=", 937, G__TSlsDetectorDict_87_0_11, (int) ('u'), G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration), -1, 1, 1, 1, 1, 0, "u 'angularCalibration' - 11 - -", (char*) NULL, (void*) NULL, 0); + G__tag_memfunc_reset(); +} + + +/********************************************************* +* Member function information setup +*********************************************************/ +extern "C" void G__cpp_setup_memfuncTSlsDetectorDict() { +} + +/********************************************************* +* Global variable information setup for each class +*********************************************************/ +static void G__cpp_setup_global0() { + + /* Setting up global variables */ + G__resetplocal(); + + + G__resetglobalenv(); +} +extern "C" void G__cpp_setup_globalTSlsDetectorDict() { + G__cpp_setup_global0(); +} + +/********************************************************* +* Global function information setup for each class +*********************************************************/ +static void G__cpp_setup_func0() { + G__lastifuncposition(); + +} + +static void G__cpp_setup_func1() { +} + +static void G__cpp_setup_func2() { + + G__resetifuncposition(); +} + +extern "C" void G__cpp_setup_funcTSlsDetectorDict() { + G__cpp_setup_func0(); + G__cpp_setup_func1(); + G__cpp_setup_func2(); +} + +/********************************************************* +* Class,struct,union,enum tag information setup +*********************************************************/ +/* Setup class/struct taginfo */ +G__linked_taginfo G__TSlsDetectorDictLN_energyCalibrationFunctions = { "energyCalibrationFunctions" , 99 , -1 }; +G__linked_taginfo G__TSlsDetectorDictLN_energyCalibration = { "energyCalibration" , 99 , -1 }; +G__linked_taginfo G__TSlsDetectorDictLN_angularCalibration = { "angularCalibration" , 99 , -1 }; + +/* Reset class/struct taginfo */ +extern "C" void G__cpp_reset_tagtableTSlsDetectorDict() { + G__TSlsDetectorDictLN_energyCalibrationFunctions.tagnum = -1 ; + G__TSlsDetectorDictLN_energyCalibration.tagnum = -1 ; + G__TSlsDetectorDictLN_angularCalibration.tagnum = -1 ; +} + + +extern "C" void G__cpp_setup_tagtableTSlsDetectorDict() { + + /* Setting up class,struct,union tag entry */ + G__get_linked_tagnum_fwd(&G__TSlsDetectorDictLN_energyCalibrationFunctions); + G__tagtable_setup(G__get_linked_tagnum(&G__TSlsDetectorDictLN_energyCalibration),sizeof(energyCalibration),-1,1280,(char*)NULL,G__setup_memvarenergyCalibration,G__setup_memfuncenergyCalibration); + G__tagtable_setup(G__get_linked_tagnum(&G__TSlsDetectorDictLN_angularCalibration),sizeof(angularCalibration),-1,1280,(char*)NULL,G__setup_memvarangularCalibration,G__setup_memfuncangularCalibration); +} +extern "C" void G__cpp_setupTSlsDetectorDict(void) { + G__check_setup_version(30051515,"G__cpp_setupTSlsDetectorDict()"); + G__set_cpp_environmentTSlsDetectorDict(); + G__cpp_setup_tagtableTSlsDetectorDict(); + + G__cpp_setup_inheritanceTSlsDetectorDict(); + + G__cpp_setup_typetableTSlsDetectorDict(); + + G__cpp_setup_memvarTSlsDetectorDict(); + + G__cpp_setup_memfuncTSlsDetectorDict(); + G__cpp_setup_globalTSlsDetectorDict(); + G__cpp_setup_funcTSlsDetectorDict(); + + if(0==G__getsizep2memfunc()) G__get_sizep2memfuncTSlsDetectorDict(); + return; +} +class G__cpp_setup_initTSlsDetectorDict { + public: + G__cpp_setup_initTSlsDetectorDict() { G__add_setup_func("TSlsDetectorDict",(G__incsetup)(&G__cpp_setupTSlsDetectorDict)); G__call_setup_funcs(); } + ~G__cpp_setup_initTSlsDetectorDict() { G__remove_setup_func("TSlsDetectorDict"); } +}; +G__cpp_setup_initTSlsDetectorDict G__cpp_setup_initializerTSlsDetectorDict; + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/TSlsDetectorDict.h b/slsDetectorSoftware/slsDetectorAnalysis/TSlsDetectorDict.h new file mode 100644 index 000000000..0d2cea9fb --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/TSlsDetectorDict.h @@ -0,0 +1,42 @@ +/******************************************************************** +* TSlsDetectorDict.h +* CAUTION: DON'T CHANGE THIS FILE. THIS FILE IS AUTOMATICALLY GENERATED +* FROM HEADER FILES LISTED IN G__setup_cpp_environmentXXX(). +* CHANGE THOSE HEADER FILES AND REGENERATE THIS FILE. +********************************************************************/ +#ifdef __CINT__ +#error TSlsDetectorDict.h/C is only for compilation. Abort cint. +#endif +#include +#include +#include +#include +#include +#define G__ANSIHEADER +#define G__DICTIONARY +#include "cint/G__ci.h" +extern "C" { +extern void G__cpp_setup_tagtableTSlsDetectorDict(); +extern void G__cpp_setup_inheritanceTSlsDetectorDict(); +extern void G__cpp_setup_typetableTSlsDetectorDict(); +extern void G__cpp_setup_memvarTSlsDetectorDict(); +extern void G__cpp_setup_globalTSlsDetectorDict(); +extern void G__cpp_setup_memfuncTSlsDetectorDict(); +extern void G__cpp_setup_funcTSlsDetectorDict(); +extern void G__set_cpp_environmentTSlsDetectorDict(); +} + + +#include "TObject.h" +#include "TMemberInspector.h" +#include "energyCalibration.h" +#include "angularCalibration.h" + +#ifndef G__MEMFUNCBODY +#endif + +extern G__linked_taginfo G__TSlsDetectorDictLN_energyCalibrationFunctions; +extern G__linked_taginfo G__TSlsDetectorDictLN_energyCalibration; +extern G__linked_taginfo G__TSlsDetectorDictLN_angularCalibration; + +/* STUB derived class for protected member access */ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/angCalLogClass.h b/slsDetectorSoftware/slsDetectorAnalysis/angCalLogClass.h new file mode 100644 index 000000000..fdaeb308a --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/angCalLogClass.h @@ -0,0 +1,153 @@ +#ifndef ANGCALLOGCLASS_H +#define ANGCALLOGCLASS_H + +#include +#include +#ifdef __CINT__ +#define MYROOT +#endif + +#ifndef MYROOT +#include "slsDetectorCommand.h" +#include "slsDetectorUtils.h" +#include "sls_detector_defs.h" +#endif + +using namespace std; + +class angCalLogClass { + + + public: + + +#ifndef MYROOT + angCalLogClass(slsDetectorUtils *det){ createVars(); + char cmd[1000]; \ + char *argv[2]; \ + argv[0]=cmd; \ + sprintf(cmd,"_%d.angcal",det->getFileIndex()); \ + outfile.open(string(det->getFilePath()+string("/")+det->getFileName()+string(cmd)).c_str()); \ + outfile.precision(8); + myDet=new slsDetectorCommand(det); \ + if (outfile.is_open()) { \ + for (int iv=0; ivexecuteLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ + }; \ + }; \ + }; + ~angCalLogClass(){delete myDet; outfile.close();}; +#else + angCalLogClass() { createVars(); }; + ~angCalLogClass(){}; +#endif + + + int addStep(double pos, string fname) {std::cout.precision(5); outfile << pos << " " << fname << endl; return 0;}; + + + // + + int readHeader(ifstream &infile, int &maxmod, int &nmod, int &chanspermod, char *angconvfile, double &globaloff, double &fineoff, int &angdir, char *ffdir, char *fffile, char *badfile ) { \ + nmod=0; chanspermod=0; globaloff=0; fineoff=0; angdir=1; \ + strcpy(angconvfile,"none"); strcpy(ffdir,"none"); strcpy(fffile,"none"); strcpy(badfile,"none"); \ + char line[1000], myvar[100], myarg[100]; \ + float v; \ + for (int iv=0; ivcenter; \ + ecenter=acc->ecenter; \ + r_conversion=acc->r_conversion; \ + er_conversion=acc->er_conversion; \ + offset=acc->offset; \ + eoffset=acc->eoffset; \ + tilt=acc->tilt; \ + etilt=acc->etilt; \ + }; + + + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/angularCalibration.cpp b/slsDetectorSoftware/slsDetectorAnalysis/angularCalibration.cpp new file mode 100644 index 000000000..08fa890a3 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/angularCalibration.cpp @@ -0,0 +1,471 @@ +#include "angularCalibration.h" + +#include +#ifdef ROOT +#include +#include +#endif + +#include "usersFunctions.h" + +#ifdef __CINT +#include "usersFunctions.cpp" +#endif + +using namespace std; + +angularCalibration::angularCalibration(int nm): direction(1), +#ifdef ROOT + fpeak(NULL), + fangle(NULL), +#endif + encoder(0), + totalOffset(0), + ang_min(-180), + ang_max(180), + nmod(nm), + nchmod(1280), + angConv(NULL) +{ + +#ifdef ROOT +// Creates a Root function based on function peakfunction + TF1 *fpeak = new TF1("fpeak",this,&angularCalibration::peakFunction,ang_min,ang_max,5,"angularCalibration","peakFunction"); + +// Sets initial values and parameter names + // func->SetParameters((Double_t) PEAKHEIGHT, (Double_t) maxch,(Double_t) PEAKWIDTH,(Double_t) PEAKBACK); + fpeak->SetParNames("Number of Photons","Peak Position","Peak Width RMS","Background Offset", "Background Slope"); + + + TF1 *fangle = new TF1("fangle",this,&angularCalibration::angleFunction,0,1280,3,"angularCalibration","angleFunction"); + fangle->SetParNames("Center","Conversion Radius","Offset"); + +#endif + + angConv=new angleConversionConstant[nmod]; + +} + +angularCalibration::~angularCalibration(){ +#ifdef ROOT + delete fpeak; + delete fangle; + +#endif +} + + + +angleConversionConstant* angularCalibration::getAngularConversionConstant(int imod) { + if (imod>=0 && imod=0 && imodcenter; + angConv[imod].ecenter=a->ecenter; + angConv[imod].r_conversion=a->r_conversion; + angConv[imod].er_conversion=a->er_conversion; + angConv[imod].offset=a->offset; + angConv[imod].eoffset=a->eoffset; + angConv[imod].tilt=a->tilt; + angConv[imod].etilt=a->etilt; + + return angConv+imod; + } + return NULL; + + +} + + + + + +#ifdef ROOT + +Double_t angularCalibration::peakFunction(Double_t *x, Double_t *par) { + Double_t arg = 0; + if (par[2] != 0) arg = (x[0] - par[1])/par[2]; + return par[0]*TMath::Exp(-0.5*arg*arg)+par[3]+par[4]*(x[0]-par[1]); + +} + +Double_t angularCalibration::angleFunction(Double_t *x, Double_t *par) { + return par[2]-angle((int)x[0],0,0,par[1],par[0],0,0,direction); +} + + + + + + + +TF1 *fitPeak(TH1 *h) { + + TF1 *fitfun=NULL; + int chmod, imod; + double ang; + +// reads in a run and fits a gaussian to the peak as function +// of channel number also reads optical encoder + + +// find angular range in channels + +// is it necessary to discard fit with too many points? + for (int i=0;iGetNbinsX();i++) { + imod=i/nchmod; + chmod=i%(imod*nchmod); + ang=angle(chmod,encoder,totalOffset,angConv[imod].r_conversion, angConv[imod].center, angConv[imod].offset, angConv[imod].tilt, direction); + if ((ang>ang_min) && (angminang) && (angle(i)MAXINPEAK) { +// printf("too many points in angular range !\n"); +// return -1; // too many points in range +// } +// if ( data[i]> max) { +// max = (int) data[i]; +// maxch = i; +// } +// } +// } +// } else +// return -1; + +// npoints--; +// chmin= (int) x[0]; +// chmax= (int) x[npoints]; + +// printf("number of points in range %f-%f: %i \n",minang,maxang,npoints); +// printf("channel from minang to maxang %i - %i \n",chmin,chmax); +// printf("channel with max intensity %i \n",maxch); + +// TCanvas *c1; + +// TGraph *gr1 = new TGraph(npoints,anglefit,y); +// TGraph *gr2 = new TGraph(npoints,x,y); +// if (plotflag) { +// /* create canvas */ + +// c1 = new TCanvas(); +// c1->SetTitle("Si calibration data"); +// c1->Divide(1,2); + +// /* create graph */ + +// sprintf(name,"run number %i",nr); +// gr1->SetTitle(name); +// gr2->SetTitle(name); + +// c1->cd(1); +// gr1->Draw("AL*"); +// c1->cd(2); +// gr2->Draw("AL*"); +// } + +// /* do not fit if peak is close to edge of module */ +// if (abs(modfromchannel(maxch)*NCHMOD-maxch)Fit("fitpeak","B"); +// else +// gr2->Fit("fitpeak","B0"); + +// TF1 *fit = gr2->GetFunction("fitpeak"); + +// // writes the fit results into the par array +// fit->GetParameters(mypar); + +// printf("\n"); +// for (i=0;i<4;i++) { +// myerr[i] = fit->GetParError(i); // obtain fit parameter errors +// printf("parameter %i: %f +- %f \n",i,mypar[i],myerr[i]); +// } + +// chi2=fit->GetChisquare(); +// printf("chi2: %e\n",chi2); +// printf("\n\n"); + +// if (chi2>CHIMAX) { +// printf("chi2 too large!\n"); +// return -1; +// } + +// if (plotflag) +// c1->Update(); // necessary for axis titles! +// // c1->WaitPrimitive(); + +// return 0; + + return fitfun; + +} + + +#endif + + + +// // +// // for detector angular calibration +// // +// // loops over runs fits a peak in each run and then fits the parameters for +// // the angular calibration to the fitted peak and optical encoder values +// // +// // +// // note: +// // setting global offset is important to find peak in peak fitting! +// // also set peak height,width and background in defines at beginning +// // + +// void fitangle(char fname[80],char extension[10], int start, int stop, double startangle, double stopangle) { + +// int i,nfit,mod,npoints,nnpoints; +// double x[MAXINMODULE],y[MAXINMODULE],ex[MAXINMODULE],ey[MAXINMODULE],min,max; +// double xx[MAXINMODULE],yy[MAXINMODULE],exx[MAXINMODULE],eyy[MAXINMODULE]; + +// double channelfit[MAXRUN], channelerror[MAXRUN], encoderfit[MAXRUN]; +// int runnrfit[MAXRUN], modulenr[MAXRUN]; + + +// FILE *fp; +// char name[80]; +// TCanvas *c1,*c2; +// gROOT->Reset(); // reset root +// // gStyle->SetOptFit(1110); + +// nfit=0; +// for (i=start;iSetTitle("Si calibration data"); +// /* create graph for angle vs fitted channel number */ +// gr3->Draw("AL*"); + +// c1->Update(); // necessary for axis titles! +// c1->WaitPrimitive(); + +// delete c1; +// } +// TH1F *herr=new TH1F("herr","",100,0,0.002); + + +// for (mod=0;mod5) { + +// // create canvas +// if (plotflag) { +// TCanvas *c2 = new TCanvas(); +// c2->SetTitle("Si calibration data"); +// c2->Divide(1,3); +// } +// // create graph +// TGraphErrors *gr1 = new TGraphErrors(npoints,x,y,ex,ey); +// sprintf(name,"module number %i",mod); +// gr1->SetTitle(name); +// if (plotflag) { +// c2->cd(1); +// gr1->Draw("ALP"); +// } + + +// // Creates a Root function based on function anglefunction +// if (x[0]>x[npoints-1]) { +// min=x[npoints-1]; +// max=x[0]; +// } else { +// max=x[npoints-1]; +// min=x[0]; +// } + + +// TF1 *func = new TF1("fitangle",anglefunction,min,max,3); + +// // Sets initial values and parameter names +// func->SetParameters(640,0.0000656,-mod*5.0); +// func->SetParNames("center","conversion","offset"); +// func->FixParameter(0,640.0); +// if (plotflag) { +// gr1->Fit("fitangle"); // fit the function +// } else +// gr1->Fit("fitangle","0"); // fit the function + + +// // calculate the deviations of data points from fitted function and plot them +// for (i=0;iEval(x[i])-y[i]; +// } +// TGraph *gr4 = new TGraph(npoints,x,ey); +// sprintf(name,"module number %i deviations from fit",mod); +// gr4->SetTitle(name); + +// if (plotflag) { +// gr4->SetMarkerStyle(24); +// c2->cd(2); +// gr4->Draw("ALP"); +// } + + +// // iterate fit with outlying points excluded +// nnpoints=0; +// for (i=0;iFit("fitangle"); // fit the function +// } else +// gr3->Fit("fitangle","0"); // fit the function + + +// // calculate the deviations of data points from fitted function and plot them +// for (i=0;iEval(xx[i])-yy[i]; +// herr->Fill(eyy[i]); +// } + +// TGraph *gr5 = new TGraph(nnpoints,xx,eyy); +// sprintf(name,"module number %i deviations from fit second iteration",mod); +// if (plotflag) { +// c2->cd(3); +// gr5->SetTitle(name); +// gr5->SetMarkerStyle(24); + +// gr5->Draw("ALP"); + + +// c2->Update(); // necessary for axis titles? +// c2->WaitPrimitive(); + +// } + +// // writes the fit results into the par array +// // +// // get fit parameter +// func->GetParameters(mypar); + +// for (i=0;i<3;i++) { +// myerr[i] = func->GetParError(i); // obtain fit parameter errors +// printf("parameter %i: %E +- %E \n",i,mypar[i],myerr[i]); +// } +// printf("\n\n"); + +// center[mod]=mypar[0]; +// errcenter[mod]=myerr[0]; +// conversion[mod]=mypar[1]; +// errconversion[mod]=myerr[1]; +// moffset[mod]=mypar[2]; +// erroff[mod]=myerr[2]; + +// delete gr1; +// delete gr4; +// delete gr5; +// delete func; +// delete c2; +// } +// } +// //herr->GetXaxis()->SetMaxDigits(3); +// herr->GetXaxis()->SetTitle("Deviations from fit (deg)"); +// herr->Draw(); + + +// printf("\n\n\n"); +// for (mod=0;mod +#include +class TH1; +#endif + + //double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) + + + +class angularCalibration { + + public: + angularCalibration(int nm=48); + ~angularCalibration(); + + /** + sets the angular direction of the detector + \par d 1 or -1 set the angular direction, other valuse simply get + \returns the angular direction of the detector + */ + int setDirection(int d=0){if (d==-1 || d==1) direction=d; return direction;}; + + /** + sets the encoder position + \param f encoder position to be set + \returns current encoder position + */ + double setEncoder(double f) {encoder=f; return encoder;}; + + /** + gets the encoder position + \returns encoder position + */ + double getEncoder() {return encoder;}; + + /** + sets the totalOffset of the detector + \param f total offset to be set + \returns current total offset + */ + double setTotalOffset(double f) {totalOffset=f; return totalOffset;}; + + /** + gets the encoder position + \returns encoder position + */ + double getTotalOffset() {return totalOffset;}; + + + + + /** + sets the angular range for peak fitting + \param mi minimum of the angular range + \param ma maximum of the angular range + */ + void setAngularRange(double mi, double ma){ang_min=mi; ang_max=ma;}; + + + /** + gets the angular range for peak fitting + \param mi reference to the minimum of the angular range + \param ma reference to the maximum of the angular range + */ + void getAngularRange(double &mi, double &ma){mi=ang_min; ma=ang_max;}; + + + /** sets and returns the number of modules + \param nm number of modules to be set (<0 gets) + \return current number of modules + */ + int setNumberOfModules(int nm=-1) {if (nm>=0) nmod=nm; return nmod;}; + + /** sets and returns the number of channels per module + \param n number of channels per module to be set (<0 gets) + \return current number of channels per module + */ + int setChannelsPerModule(int n=-1) {if (n>0) nchmod=n; return nchmod;}; + + angleConversionConstant *getAngularConversionConstant(int imod=0); + angleConversionConstant *setAngularConversionConstant(angleConversionConstant *a, int imod=0); + + +#ifdef ROOT + + /** + Gaussian with pedestal describing a peak + par[0] is the heigh of the pean + par[1] is the peak position + par[2] is the peak width + par[3] is the background offset + par[4] is the background slope + */ + Double_t peakFunction(Double_t *x, Double_t *par); + + + /** + Angular conversion function + par[0] is the module center + par[1] is the conversion radius (pitch/radius) + par[2] is the module offset + */ + Double_t angleFunction(Double_t *x, Double_t *par); + + /** + Fits a peak for the angular calibration + \param h histogram channels versus intensity + \returns fitted function or NULL if fit failed + */ + TF1 *fitPeak(TH1 *h); + +#endif + + + private: + + int direction; /**< angular direction of the detector -can be +1 or -1 */ + +#ifdef ROOT + TF1 *fpeak; /**< Root function based on function peakFunction */ + + TF1 *fangle; /**< Root function based on function angleFunction */ + +#endif + double encoder; /**< position of the detector encoder */ + double totalOffset; /**< total offset of the detector */ + double ang_min; /**< minimum of the angular range for peak fitting*/ + double ang_max; /**< maximum of the angular range for peak fitting */ + + int nmod; + int nchmod; + + angleConversionConstant angConv[MAXMOD*MAXDET]; + + + + + +/* void fitangle(char fname[80],char extension[10], int start, int stop, double startangle, double stopangle); //fits all datasets and extracts the constants */ +/* int fitpeak(char fname[80],char extension[10], int nr, double minang, double maxang); // fits a peak from a pattern using nominal calibration constant */ + + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/angularConversion.cpp b/slsDetectorSoftware/slsDetectorAnalysis/angularConversion.cpp new file mode 100644 index 000000000..226e2dbc0 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/angularConversion.cpp @@ -0,0 +1,308 @@ +#include "angularConversion.h" + +#include +#include +#include +#include +#include + + +using namespace std; + +angularConversion::angularConversion(): angularConversionStatic(), currentPosition(0), + currentPositionIndex(0) + +{ + //angleFunctionPointer=0; + // registerAngleFunctionCallback(&defaultAngleFunction); + +} + +angularConversion::~angularConversion(){ + +} + + + + +double* angularConversion::convertAngles(double pos) { + + int nmod=getNMods(); + int *chansPerMod=new int[nmod]; + angleConversionConstant **angOff=new angleConversionConstant*[nmod]; + int *mF=new int[nmod]; + double fo=*fineOffset; + double go=*globalOffset; + int angdir=*angDirection; + + + + for (int im=0; im0) { + *binSize=v; + nBins=(int)(360./(*binSize))+1; + } + return *binSize; + case MOVE_FLAG: + if (moveFlag) { + if (v>0) + *moveFlag=1; + else if (v==0) + *moveFlag=0; + return *moveFlag; + } + return -1; + case SAMPLE_X: + if (sampleDisplacement) { + sampleDisplacement[X]=v; + return sampleDisplacement[X]; + } + return 0; + case SAMPLE_Y: + if (sampleDisplacement) { + sampleDisplacement[Y]=v; + return sampleDisplacement[Y]; + } + return 0; + default: + return 0; + } +} + + /** + returns the value of an angular conversion parameter + \param c can be ANGULAR_DIRECTION, GLOBAL_OFFSET, FINE_OFFSET, BIN_SIZE + \returns the actual value + + */ + +double angularConversion::getAngularConversionParameter(angleConversionParameter c) { + + switch (c) { + case ANGULAR_DIRECTION: + return *angDirection; + case GLOBAL_OFFSET: + return *globalOffset; + case FINE_OFFSET: + return *fineOffset; + case BIN_SIZE: + if (*binSize>0) + nBins=(int)(360./(*binSize))+1; + else + nBins=0; + return *binSize; + case MOVE_FLAG: + if (moveFlag) + return *moveFlag; + else + return -1; + default: + return 0; + } +} + + + + +int angularConversion::setAngularConversionFile(string fname) { + if (fname=="") { + setAngularCorrectionMask(0); +#ifdef VERBOSE + std::cout << "Unsetting angular conversion" << std::endl; +#endif + } else { + if (fname=="default") { + fname=string(angConvFile); + } + +#ifdef VERBOSE + std::cout << "Setting angular conversion to " << fname << std:: endl; +#endif + if (readAngularConversionFile(fname)>=0) { + setAngularCorrectionMask(1); + strcpy(angConvFile,fname.c_str()); + } + } + return setAngularCorrectionMask(); +} + + + + + + /* + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ +int angularConversion::setPositions(int nPos, double *pos){ + if (nPos>=0) + *numberOfPositions=nPos; + for (int ip=0; ip +#include + +#include "angularConversionStatic.h" + + //double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) + + +using namespace std; + +/** + @short Angular conversion constants needed for a detector module + */ + + +/** + +@short methods to set/unset the angular conversion and merge the data +class containing the methods to set/unset the angular conversion and merge the data + + +The angular conversion itself is defined by the angle() function defined in usersFunctions.cpp + +*/ +class angularConversion : public virtual slsDetectorBase, public angularConversionStatic + +{ + + public: + /** default constructor */ + angularConversion(); + /** virtual destructor */ + virtual ~angularConversion(); + + + + //virtual int readAngularConversion(string fname)=0; + + using angularConversionStatic::writeAngularConversion; + using angularConversionStatic::readAngularConversion; + + + + /** + pure virtual function + \param file name to be written (nmod and array of angular conversion constants default to the ones ot the slsDetector + */ + virtual int writeAngularConversion(string fname)=0; + /** + sets the arrays of the merged data to 0. NB The array should be created with size >= 360./getBinSize(); + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns OK or FAIL + */ + int resetMerging(double *mp, double *mv,double *me, int *mm); + + /** + creates the arrays for merging the data and sets them to 0. + */ + int resetMerging(); + + + /** + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param badChanMask badchannelmask (if NULL does not correct for bad channels) + \returns OK or FAIL + */ + + int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int *badChanMask); + /** + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param badChanMask badchannelmask (if NULL does not correct for bad channels) + \returns OK or FAIL + */ + + int addToMerging(double *p1, double *v1, double *e1,int *badChanMask); + + /** + calculates the "final" positions, data value and errors for the merged data + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) + */ + + int finalizeMerging(double *mp, double *mv,double *me, int *mm); + +/** + calculates the "final" positions, data value and errors for the merged data + \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) + */ + + int finalizeMerging(); + + + /** + set detector global offset + \param f global offset to be set + \returns actual global offset + */ + double setGlobalOffset(double f){return setAngularConversionParameter(GLOBAL_OFFSET,f);}; + + + /** + set detector fine offset + \param f global fine to be set + \returns actual fine offset + */ + double setFineOffset(double f){return setAngularConversionParameter(FINE_OFFSET,f);}; + + /** + get detector fine offset + \returns actual fine offset + */ + double getFineOffset(){return getAngularConversionParameter(FINE_OFFSET);}; + + /** + get detector global offset + \returns actual global offset + */ + double getGlobalOffset(){return getAngularConversionParameter(GLOBAL_OFFSET);}; + + /** + + set detector bin size + \param bs bin size to be set + \returns actual bin size + */ + double setBinSize(double bs){if (bs>0) nBins=(int)(360./bs); return setAngularConversionParameter(BIN_SIZE,bs);}; + + /** + get detector bin size + \returns detector bin size used for merging (approx angular resolution) + */ + double getBinSize() {return getAngularConversionParameter(BIN_SIZE);}; + + + + /** + + get angular direction + \returns actual angular direction (1 is channel number increasing with angle, -1 decreasing) + */ + int getAngularDirection(){return (int)getAngularConversionParameter(ANGULAR_DIRECTION);}; + + + /** + + set angular direction + \param d angular direction to be set (1 is channel number increasing with angle, -1 decreasing) + \returns actual angular direction (1 is channel number increasing with angle, -1 decreasing) + */ + int setAngularDirection(int d){return (int)setAngularConversionParameter(ANGULAR_DIRECTION, (double)d);}; + + /** + \returns number of angular bins in the merging (360./binsize) + */ + int getNumberOfAngularBins(){return nBins;}; + + /** + get angular conversion + \param direction reference to diffractometer direction + \param angconv array that will be filled with the angular conversion constants + \returns 0 if angular conversion disabled, >0 otherwise + */ + virtual int getAngularConversion(int &direction, angleConversionConstant *angconv=NULL)=0; + + + /** + set angular conversion parameter + \param c parameter type (globaloffset, fineoffset, binsize, angular direction, move flag) + \param v value to be set + \returns actual value + */ + double setAngularConversionParameter(angleConversionParameter c, double v); + /** + get angular conversion parameter + \param c parameter type (globaloffset, fineoffset, binsize, angular direction, move flag) + \returns actual value + */ + double getAngularConversionParameter(angleConversionParameter c); + + + + + /** + set positions for the acquisition + \param nPos number of positions + \param pos array with the encoder positions + \returns number of positions + */ + virtual int setPositions(int nPos, double *pos); + /** + get positions for the acquisition + \param pos array which will contain the encoder positions + \returns number of positions + */ + virtual int getPositions(double *pos=NULL); + + /** + deletes the array of merged data + \returns OK + */ + int deleteMerging(); + + /** + \returns pointer to the array o merged positions + */ + double *getMergedPositions(){return mergingBins;}; + /** + \returns pointer to the array of merged counts + */ + double *getMergedCounts(){return mergingCounts;}; + /** + \returns pointer to the array of merged errors + */ + double *getMergedErrors(){return mergingErrors;}; + + + + /** + sets the angular conversion file + \param fname file to read + \returns angular conversion flag + */ + + int setAngularConversionFile(string fname); + + + /** + returns the angular conversion file + */ + string getAngularConversionFile(){if (setAngularCorrectionMask()) return string(angConvFile); else return string("none");}; + + + /** + reads teh angular conversion file for the (multi)detector and writes it to shared memory + */ + virtual int readAngularConversionFile(string fname="")=0; + + + + + + /** + \returns number of modules of the (multi)detector + */ + virtual int getNMods()=0; + + /** + returns number of channels in the module + \param imod module number + \returns number of channels in the module + */ + virtual int getChansPerMod(int imod=0)=0; + + /** + get the angular conversion contant of one modules + \param imod module number + \returns pointer to the angular conversion constant + */ + virtual angleConversionConstant *getAngularConversionPointer(int imod=0)=0; + + /** + converts channel number to angle + \param pos encoder position + \returns array of angles corresponding to the channels + */ + double* convertAngles(double pos); + + + + /** + converts channel number to angle for the current encoder position + \returns array of angles corresponding to the channels + */ + double *convertAngles(){return convertAngles(currentPosition);}; + + /** + \param imod module number + \returns move flag of the module (1 encoder is added to the angle, 0 not) + Shold be module dependent! + */ + virtual int getMoveFlag(int imod)=0; + + /** + returns number of positions + */ + int getNumberOfPositions() {return *numberOfPositions;}; + + + + protected: + + + /** pointer to number of positions for the acquisition*/ + int *numberOfPositions; + + /** pointer to the detector positions for the acquisition*/ + double *detPositions; + + /** pointer to angular conversion file name*/ + char *angConvFile; + + /** pointer to angular bin size*/ + double *binSize; + + /** pointer to beamlien fine offset*/ + double *fineOffset; + /** pointer to beamlien global offset*/ + double *globalOffset; + /** pointer to beamlien angular direction*/ + int *angDirection; + /** pointer to detector move flag (1 moves with encoder, 0 not)*/ + int *moveFlag; + + /** number of bins for angular conversion (360./binsize)*/ + int nBins; + + + + double *sampleDisplacement; + + /** + current position of the detector + */ + double currentPosition; + /** + current position index of the detector + */ + int currentPositionIndex; + + + /** + enables/disable the angular conversion + \param i 1 sets, 0 unsets,, -1 gets + \returns actual angular conversion flag + */ + virtual int setAngularCorrectionMask(int i=-1)=0; + + /** + returns current position index + */ + int getCurrentPositionIndex() {return currentPositionIndex;}; + void incrementPositionIndex() {currentPositionIndex++;}; + void resetPositionIndex() {currentPositionIndex=0;}; + + + + + + + private: + + + + + // int nChans; + // int nMods; + // int chansPerMod; + // int moveFlag; + + + + + /** merging bins */ + double *mergingBins; + + /** merging counts */ + double *mergingCounts; + + /** merging errors */ + double *mergingErrors; + + /** merging multiplicity */ + int *mergingMultiplicity; + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.cpp b/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.cpp new file mode 100644 index 000000000..43e5a4436 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.cpp @@ -0,0 +1,461 @@ +#include "angularConversionStatic.h" + +#include +#include +#include +#include +#include "angleConversionConstant.h" + +#include "sls_detector_defs.h" +#include "angleFunction.h" +using namespace std; + +angularConversionStatic::angularConversionStatic() +{ + //angleFunctionPointer=0; + registerAngleFunctionCallback(&defaultAngleFunction); + +} + +angularConversionStatic::~angularConversionStatic(){ + +} + + + +double* angularConversionStatic::convertAngles(double pos, int nch, int *chansPerMod, angleConversionConstant **angOff, int *mF, double fo, double go, int angdir) { + + // cout << "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP convert angles " << endl; + + int imod=0; + double *ang=new double[nch]; + double enc=pos; + angleConversionConstant *p=NULL; + + int ch0=0; + int chlast=chansPerMod[0]-1; + int nchmod=chansPerMod[0]; + p=angOff[imod]; + if (mF[imod]==0) + enc=0; + else + enc=pos; + + for (int ip=0; ipchlast) { + imod++; + p=angOff[imod]; + if (mF[imod]==0) + enc=0; + else + enc=pos; + +#ifdef VERBOSE + if (p) + cout << enc << endl << fo+go << endl << p->r_conversion << endl << p->center << endl << p->offset << endl << p->tilt << angdir << endl; + else + cout << "no ang conv " << endl; +#endif + + ch0=chlast+1; + nchmod=chansPerMod[imod]; + if (nchmod>0) + chlast=ch0+nchmod-1; + } + + if (p) + ang[ip]=angle(ip-ch0, \ + enc, \ + fo+go, \ + p->r_conversion, \ + p->center, \ + p->offset, \ + p->tilt, \ + angdir ); +#ifdef VERBOSE + cout << "ip " << ip << " ch0 " << ch0 << " chlast " << chlast << " imod " << imod << endl; +#endif + } + return ang; +} + + + + + + +double angularConversionStatic::convertAngle(double pos, int ich, angleConversionConstant *p, int mF, double fo, double go, int angdir) { + + // cout << "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP convert angle " << endl; + // if (p) + // cout << pos << endl << fo+go << endl << p->r_conversion << endl << p->center << endl << p->offset << endl << mF << endl << angdir << endl; + // else + // cout << "no ang conv " << endl; + + double enc=0, trans=0; + double ang; + + switch (mF) { + case 0: + enc=0; + trans=0; + break; + case 1: + enc=pos; + trans=0; + break; + case -1: + enc=-pos; + trans=0; + break; + case 2: + enc=0; + trans=pos; + break; + case -2: + enc=0; + trans=-pos; + break; + default: + enc=0; + trans=0; + } + + if (p) + ang=angle(ich, \ + enc, \ + fo+go, \ + p->r_conversion, \ + p->center, \ + p->offset, \ + trans, \ + angdir ); + // cout << ich << " " << ang << endl << endl; + return ang; + + + +} + + + + + + + + + + + +double angularConversionStatic::convertAngle(double pos, int ich, int *chansPerMod, angleConversionConstant **angOff, int *mF, double fo, double go, int angdir) { + + // cout << "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP convert angles xx" << endl; + int imod=0; + double ang; + // double enc=0, trans=0; + angleConversionConstant *p=NULL; + + int ch0=0; + int chlast=chansPerMod[0]-1; + int nchmod=chansPerMod[0]; + + + + while (ich>chlast) { + imod++; + ch0=chlast+1; + nchmod=chansPerMod[imod]; + chlast=ch0+nchmod-1; + } + + p=angOff[imod]; + + + ang=convertAngle(pos, ich-ch0, p, mF[imod], fo, go, angdir); + + return ang; + +} + + + +//static! +int angularConversionStatic::readAngularConversion(string fname, int nmod, angleConversionConstant *angOff) { + + ifstream infile; + string ss; + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + readAngularConversion(infile, nmod, angOff); + infile.close(); + } else { + std::cout<< "Could not open calibration file "<< fname << std::endl; + return -1; + } + return 0; +} + + +//static +int angularConversionStatic::readAngularConversion( ifstream& infile, int nmod, angleConversionConstant *angOff) { + string str; + int mod; + double center, ecenter, pitch, epitch; + double r_conv, er_conv; + double off, eoff; + string ss; + int interrupt=0; + int nm=0; + int newangconv=0; + //" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n" + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + cout << "** mod " << nm << " " ; + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> ss >> mod; + ssstr >> ss >> center; + if (ss==string("center")) + newangconv=0; + else + newangconv=1; + ssstr >> ss >> ecenter; + if (newangconv) { + ssstr >> ss >> pitch; + ssstr >> ss >> epitch; + } + ssstr >> ss >> r_conv; + ssstr >> ss >> er_conv; + ssstr >> ss >> off; + ssstr >> ss >> eoff; +#ifdef VERBOSE + cout << nm << " " << nmod << endl; +#endif + if (nm=0 ) { + angOff[nm].center=center; + angOff[nm].r_conversion=r_conv; + angOff[nm].offset=off; + angOff[nm].ecenter=ecenter; + angOff[nm].er_conversion=er_conv; + angOff[nm].eoffset=eoff; + + if (newangconv!=0) { + // } else { + + angOff[nm].tilt=pitch; + angOff[nm].etilt=epitch; + + } + // cout << angOff[nm].center << " " << \ + // angOff[nm].r_conversion << " " << \ + // angOff[nm].offset << endl; + + } else + break; +#ifdef VERBOSE + cout << nm<<" " << angOff[nm].offset << endl; +#endif + nm++; + if (nm>=nmod) + break; + + + + + } + return nm; + } + +//static +int angularConversionStatic:: writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff) { + + ofstream outfile; + outfile.open (fname.c_str(),ios_base::out); + if (outfile.is_open()) + { + writeAngularConversion(outfile, nmod, angOff); + outfile.close(); + } else { + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; + return -1; + } + //" module %i center %E +- %E conversion %E +- %E offset %f +- %f \n" + return 0; +} + + + +//static +int angularConversionStatic:: writeAngularConversion(ofstream& outfile, int nmod, angleConversionConstant *angOff) { + + for (int imod=0; imod0) { + #ifdef VERBOSE + cout << "finalize " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< " " << mv[ibin] << " " << me[ibin] << endl; + #endif + mp[np]=mp[ibin]/mm[ibin]; + mv[np]=mv[ibin]/mm[ibin]; + me[np]=me[ibin]/mm[ibin]; + me[np]=sqrt(me[ibin]); + mm[np]=mm[ibin]; + np++; + } + } + // cout << endl ; + return np; +} + +//static +int angularConversionStatic::addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nbins, int *badChanMask ) { + + + // cout << "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP add to merging " << endl; + double binmi=-180.; + int ibin=0; + + if (p1==NULL) + return 0; + if (v1==NULL) + return slsDetectorDefs::FAIL; + + if (mp==NULL) //can be changed if we want to use a fixed bin algorithm! + return slsDetectorDefs::FAIL; + + if (mv==NULL) + return slsDetectorDefs::FAIL; + if (me==NULL) + return slsDetectorDefs::FAIL; + if (mm==NULL) + return slsDetectorDefs::FAIL; + if (nchans==0) + return slsDetectorDefs::FAIL; + + if (binsize<=0) + return slsDetectorDefs::FAIL; + + if (nbins<=0) + return slsDetectorDefs::FAIL; + + for (int ip=0; ip=0) { + mp[ibin]+=p1[ip]; + mv[ibin]+=v1[ip]; + if (e1) + me[ibin]+=(e1[ip]*e1[ip]); + else + me[ibin]+=v1[ip]; + mm[ibin]++; + +// #ifdef VERBOSE +// cout << "add " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl; +// #endif + } else + return slsDetectorDefs::FAIL; + } + + + return slsDetectorDefs::OK; + +} + +int angularConversionStatic::addPointToMerging(double p1, double v1, double e1, double *mp, double *mv,double *me, int *mm, double binsize,int nbins) { + + + // cout << "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP add point to merging "<< v1 << " " << e1 << endl; + double binmi=-180.; + int ibin=0; + + + if (mp==NULL) //can be changed if we want to use a fixed bin algorithm! + return slsDetectorDefs::FAIL; + + if (mv==NULL) + return slsDetectorDefs::FAIL; + if (me==NULL) + return slsDetectorDefs::FAIL; + if (mm==NULL) + return slsDetectorDefs::FAIL; + + if (binsize<=0) + return slsDetectorDefs::FAIL; + + if (nbins<=0) + return slsDetectorDefs::FAIL; + + + ibin=(int)((p1-binmi)/binsize); + + + if (ibin=0) { + // cout << "before " << ibin << " " << mp[ibin] << " " << mv[ibin] << " " << me[ibin] << endl; + mp[ibin]+=p1; + mv[ibin]+=v1; + if (e1) + me[ibin]+=(e1*e1); + else + me[ibin]+=v1; + mm[ibin]++; + // cout << "after " << ibin << " " << mp[ibin] << " " << mv[ibin] << " " << me[ibin] << endl; + +// #ifdef VERBOSE +// cout << "add " << ibin << " "<< mm[ibin] << " " << mp[ibin]<< mv[ibin] << me[ibin] << endl; +// #endif + } else { + cout << "Bin out of range! " << ibin << endl; + return slsDetectorDefs::FAIL; + } + + return slsDetectorDefs::OK; + +} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.h b/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.h new file mode 100644 index 000000000..4ecd9d57d --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/angularConversionStatic.h @@ -0,0 +1,184 @@ + +#ifndef ANGULARCONVERSIONSTATIC_H +#define ANGULARCONVERSIONSTATIC_H + +#ifdef __CINT +#define MYROOT +#endif + + + + +#include +#include + +//#include "angleConversionConstant.h" + + + //double angle(int ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) + +class angleConversionConstant; + +using namespace std; + +/** + @short Angular conversion constants needed for a detector module + */ + + +/** + +@short methods to set/unset the angular conversion and merge the data +class containing the methods to set/unset the angular conversion and merge the data + + +The angular conversion itself is defined by the angle() function defined in usersFunctions.cpp + +*/ +class angularConversionStatic +// : public virtual slsDetectorDefs +{ + + public: + /** default constructor */ + angularConversionStatic(); + /** virtual destructor */ + virtual ~angularConversionStatic(); + + + + //virtual int readAngularConversion(string fname)=0; + + + + + /** + + reads an angular conversion file + \param fname file to be read + \param nmod number of modules (maximum) to be read + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + */ + static int readAngularConversion(string fname, int nmod, angleConversionConstant *angOff); + + /** + reads an angular conversion file + \param ifstream input file stream to be read + \param nmod number of modules (maximum) to be read + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + + */ + static int readAngularConversion(ifstream& ifs, int nmod, angleConversionConstant *angOff); + /** + writes an angular conversion file + \param fname file to be written + \param nmod number of modules to be written + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + */ + static int writeAngularConversion(string fname, int nmod, angleConversionConstant *angOff); + + /** + writes an angular conversion file + \param ofstream output file stream + \param nmod number of modules to be written + \param angOff pointer to array of angleConversionConstants + \returns OK or FAIL + */ + static int writeAngularConversion(ofstream& ofs, int nmod, angleConversionConstant *angOff); + + /** + sets the arrays of the merged data to 0. NB The array should be created with size nbins >= 360./getBinSize(); + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param nbins number of bins + \returns OK or FAIL + */ + static int resetMerging(double *mp, double *mv,double *me, int *mm, int nbins); + + /** + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param nchans number of channels + \param binsize size of angular bin + \param nb number of angular bins + \param badChanMask badchannelmask (if NULL does not correct for bad channels) + \returns OK or FAIL + */ + + static int addToMerging(double *p1, double *v1, double *e1, double *mp, double *mv,double *me, int *mm, int nchans, double binsize,int nb, int *badChanMask=NULL); + + + /** + merge dataset + \param p1 angular positions of dataset + \param v1 data + \param e1 errors + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param nchans number of channels + \param binsize size of angular bin + \param nb number of angular bins + \param badChanMask badchannelmask (if NULL does not correct for bad channels) + \returns OK or FAIL + */ + + static int addPointToMerging(double p1, double v1, double e1, double *mp, double *mv,double *me, int *mm, double binsize, int nb); + + + /** + calculates the "final" positions, data value and errors for the merged data + \param mp already merged postions + \param mv already merged data + \param me already merged errors (squared sum) + \param mm multiplicity of merged arrays + \param nb number of bins + \returns FAIL or the number of non empty bins (i.e. points belonging to the pattern) + */ + + static int finalizeMerging(double *mp, double *mv,double *me, int *mm, int nb); + + /** + converts channel number to angle + \param pos encoder position + \returns array of angles corresponding to the channels + */ + + double* convertAngles(double pos, int nch, int *chansPerMod, angleConversionConstant **angOff, int *mF, double fo, double go, int angdir); + + double convertAngle(double pos, int ich, int *chansPerMod, angleConversionConstant **angOff, int *mF, double fo, double go, int angdir); + + + double convertAngle(double pos, int ich, angleConversionConstant *angOff, int mF, double fo, double go, int angdir); + + + + protected: + + + + + int registerAngleFunctionCallback(double (*fun)(double, double, double, double, double, double, double, int)) {angle = fun; return 0;}; + + + double (*angle)(double, double, double, double, double, double, double, int); + + + // private: + + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/badChannelCorrections.h b/slsDetectorSoftware/slsDetectorAnalysis/badChannelCorrections.h new file mode 100644 index 000000000..72e6d3590 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/badChannelCorrections.h @@ -0,0 +1,69 @@ +#ifndef BAD_CHANNEL_CORRECTIONS_H +#define BAD_CHANNEL_CORRECTIONS_H + + +#include +#include +#include +#include + +using namespace std; +class badChannelCorrections{ + + public: + + static int readBadChannelCorrectionFile(string fname, int &nbad, int *badlist){ ifstream infile(fname.c_str()); int nb=-1; if (infile.is_open()) {nb=readBadChannelCorrectionFile(infile,nbad,badlist); infile.close();}; return nb;}; + + + + static int readBadChannelCorrectionFile(ifstream &infile, int &nbad, int *badlist, int moff=0){ \ + int interrupt=0; \ + int ich; \ + int chmin,chmax; \ + string str; \ + nbad=0; \ + while (infile.good() and interrupt==0) { \ + getline(infile,str); \ + istringstream ssstr; \ + ssstr.str(str); \ + if (ssstr.bad() || ssstr.fail() || infile.eof()) { \ + interrupt=1; \ + break; \ + } \ + if (str.find('-')!=string::npos) { \ + ssstr >> chmin ; \ + ssstr.str(str.substr(str.find('-')+1,str.size())); \ + ssstr >> chmax; \ + for (ich=chmin; ich<=chmax; ich++) { \ + badlist[nbad]=ich; \ + nbad++; \ + } \ + } else { \ + ssstr >> ich; \ + badlist[nbad]=ich; \ + nbad++; \ + } \ + } \ + return nbad; }; + + + static int setBadChannelCorrection(ifstream &infile, int &nbad, int *badlist, int moff){ \ + int retval=readBadChannelCorrectionFile(infile,nbad,badlist); \ + for (int ich=0; ich +#include +#ifndef DETECTOR_DATA_H +#define DETECTOR_DATA_H +/** + @short data structure to hold the detector data after postprocessing (e.g. to plot, store in a root tree etc.) + */ +class detectorData { + public: + /** @short The constructor + \param val pointer to the data + \param err pointer to errors + \param ang pointer to the angles + \param f_ind file index + \param fname file name to which the data are saved + \param np number of points in x coordinate defaults to the number of detector channels (1D detector) + \param ny dimension in y (1D detector) + */ + detectorData(double *val=NULL, double *err=NULL, double *ang=NULL, double p_ind=-1, const char *fname="", int np=-1, int ny=1) : values(val), errors(err), angles(ang), progressIndex(p_ind), npoints(np), npy(ny){strcpy(fileName,fname);}; + /** + @short The destructor + deletes also the arrays pointing to data/errors/angles if not NULL + */ + ~detectorData() {if (values) delete [] values; if (errors) delete [] errors; if (angles) delete [] angles;}; + //private: + double *values; /**< @short pointer to the data */ + double *errors; /**< @short pointer to the errors */ + double *angles;/**< @short pointer to the angles (NULL if no angular conversion) */ + double progressIndex;/**< @short file index */ + char fileName[1000];/**< @short file name */ + int npoints;/**< @short number of points */ + int npy;/**< @short dimensions in y coordinate*/ +}; + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/annotated.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/annotated.html new file mode 100644 index 000000000..0af77f9f8 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/annotated.html @@ -0,0 +1,28 @@ + + +Class List + + + + + + +

Class List

Here are the classes, structs, unions and interfaces with brief descriptions: + + +
energyCalibration
energyCalibrationFunctionsEnergy calibration functions
+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibration-members.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibration-members.html new file mode 100644 index 000000000..4923725d9 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibration-members.html @@ -0,0 +1,55 @@ + + +Member List + + + + + + +

energyCalibration Member List

This is the complete list of members for energyCalibration, including all inherited members.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
amplenergyCalibration [private]
bg_offsetenergyCalibration [private]
bg_slopeenergyCalibration [private]
calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral=1)energyCalibration [private]
calibrateScurves(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff)energyCalibration [inline]
calibrateSpectra(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff)energyCalibration [inline]
cs_flagenergyCalibration [private]
cs_slopeenergyCalibration [private]
energyCalibration()energyCalibration
fit_maxenergyCalibration [private]
fit_minenergyCalibration [private]
fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar)energyCalibration [private]
fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar)energyCalibration
fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar)energyCalibration
flexenergyCalibration [private]
fscurveenergyCalibration [private]
fspectrumenergyCalibration [private]
funcsenergyCalibration [private]
getFitRange(Double_t &mi, Double_t &ma)energyCalibration [inline]
getStartParameters(Double_t *par)energyCalibration
initFitFunction(TF1 *fun, TH1 *h1)energyCalibration [private]
linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff)energyCalibration
noiseenergyCalibration [private]
plot_flagenergyCalibration [private]
setChargeSharing(int p=-1)energyCalibration
setFitRange(Double_t mi, Double_t ma)energyCalibration [inline]
setPlotFlag(int p=-1)energyCalibration [inline]
setScanSign(int s=0)energyCalibration [inline]
setStartParameters(Double_t *par)energyCalibration
~energyCalibration()energyCalibration


Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibration.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibration.html new file mode 100644 index 000000000..5ad0b2776 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibration.html @@ -0,0 +1,1026 @@ + + +energyCalibration Class Reference + + + + + + +

energyCalibration Class Reference

#include <energyCalibration.h> +

+List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Member Functions

 energyCalibration ()
 ~energyCalibration ()
int setPlotFlag (int p=-1)
int setScanSign (int s=0)
int setChargeSharing (int p=-1)
void setFitRange (Double_t mi, Double_t ma)
void getFitRange (Double_t &mi, Double_t &ma)
void setStartParameters (Double_t *par)
void getStartParameters (Double_t *par)
TF1 * fitSCurve (TH1 *h1, Double_t *mypar, Double_t *emypar)
TF1 * fitSpectrum (TH1 *h1, Double_t *mypar, Double_t *emypar)
TGraphErrors * linearCalibration (int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff)
TGraphErrors * calibrateScurves (int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff)
TGraphErrors * calibrateSpectra (int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff)

Private Member Functions

TGraphErrors * calibrate (int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral=1)
void initFitFunction (TF1 *fun, TH1 *h1)
TF1 * fitFunction (TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar)

Private Attributes

int plot_flag
int cs_flag
Double_t fit_min
Double_t fit_max
Double_t bg_offset
Double_t bg_slope
Double_t flex
Double_t noise
Double_t ampl
Double_t cs_slope
energyCalibrationFunctionsfuncs
TF1 * fscurve
TF1 * fspectrum
+


Detailed Description

+class alowing the energy calibration of photon counting and anlogue detectors +

+


Constructor & Destructor Documentation

+ +
+
+ + + + + + + + +
energyCalibration::energyCalibration (  ) 
+
+
+ +

+default constructor - creates the function with which the s-curves will be fitted +

+

+ +

+
+ + + + + + + + +
energyCalibration::~energyCalibration (  ) 
+
+
+ +

+default destructor - deletes the function with which the s-curves will be fitted +

+

+


Member Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TGraphErrors* energyCalibration::calibrate (int  nscan,
Double_t *  en,
Double_t *  een,
TH1F **  h1,
Double_t &  gain,
Double_t &  off,
Double_t &  egain,
Double_t &  eoff,
int  integral = 1 
) [private]
+
+
+ +

+calculates gain and offset for the set of energies

Parameters:
+ + + + + + + + +
nscan number of energy scans
en array of energies (nscan long)
een array of errors on energies (nscan long) - can be NULL!
h1 array of TH1
gain reference to gain resulting from the fit
offset reference to offset resulting from the fit
integral 1 is an s-curve set (default), 0 spectra
+
+
Returns:
graph energy vs peak/inflection point
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TGraphErrors* energyCalibration::calibrateScurves (int  nscan,
Double_t *  en,
Double_t *  een,
TH1F **  h1,
Double_t &  gain,
Double_t &  off,
Double_t &  egain,
Double_t &  eoff 
) [inline]
+
+
+ +

+calculates gain and offset for the set of energy scans

Parameters:
+ + + + + + + + + +
nscan number of energy scans
en array of energies (nscan long)
een array of errors on energies (nscan long) - can be NULL!
h1 array of TH1
gain reference to gain resulting from the fit
off reference to offset resulting from the fit
egain reference to error on the gain resulting from the fit
eoff reference to the error on the offset resulting from the fit
+
+
Returns:
graph energy vs inflection point
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TGraphErrors* energyCalibration::calibrateSpectra (int  nscan,
Double_t *  en,
Double_t *  een,
TH1F **  h1,
Double_t &  gain,
Double_t &  off,
Double_t &  egain,
Double_t &  eoff 
) [inline]
+
+
+ +

+calculates gain and offset for the set of energy spectra

Parameters:
+ + + + + + + + + +
nscan number of energy scans
en array of energies (nscan long)
een array of errors on energies (nscan long) - can be NULL!
h1 array of TH1
gain reference to gain resulting from the fit
off reference to offset resulting from the fit
egain reference to error on the gain resulting from the fit
eoff reference to the error on the offset resulting from the fit
+
+
Returns:
graph energy vs peak
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TF1* energyCalibration::fitFunction (TF1 *  fun,
TH1 *  h1,
Double_t *  mypar,
Double_t *  emypar 
) [private]
+
+
+ +

+Perfors the fit according to the flags specified and returns the fitted function

Parameters:
+ + + + + +
fun function to fit
h1 histogram to fit
mypar pointer to fit parameters array
emypar pointer to fit parameter errors
+
+
Returns:
the fitted function - can be used e.g. to get the Chi2 or similar
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
TF1* energyCalibration::fitSCurve (TH1 *  h1,
Double_t *  mypar,
Double_t *  emypar 
)
+
+
+ +

+fits histogram with the s-curve function

Parameters:
+ + + + +
h1 1d-histogram to be fitted
mypar pointer to fit parameters array
emypar pointer to fit parameter errors
+
+
Returns:
the fitted function - can be used e.g. to get the Chi2 or similar
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
TF1* energyCalibration::fitSpectrum (TH1 *  h1,
Double_t *  mypar,
Double_t *  emypar 
)
+
+
+ +

+fits histogram with the spectrum

Parameters:
+ + + + +
h1 1d-histogram to be fitted
mypar pointer to fit parameters array
emypar pointer to fit parameter errors
+
+
Returns:
the fitted function - can be used e.g. to get the Chi2 or similar
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
void energyCalibration::getFitRange (Double_t &  mi,
Double_t &  ma 
) [inline]
+
+
+ +

+gets the s-curve fit range

Parameters:
+ + + +
mi reference for minimum of the fit range (-1 is histogram x-min)
ma reference for maximum of the fit range (-1 is histogram x-max)
+
+ +
+

+ +

+
+ + + + + + + + + +
void energyCalibration::getStartParameters (Double_t *  par  ) 
+
+
+ +

+get start parameters for the s-curve function

Parameters:
+ + +
par parameters, -1 means auto-calculated par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive
+
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
void energyCalibration::initFitFunction (TF1 *  fun,
TH1 *  h1 
) [private]
+
+
+ +

+Initializes the start parameters and the range of the fit depending on the histogram characteristics and/or on the start parameters specified by the user

Parameters:
+ + + +
fun pointer to function to be initialized
h1 histogram from which to extract the range and start parameters, if not already specified by the user
+
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TGraphErrors* energyCalibration::linearCalibration (int  nscan,
Double_t *  en,
Double_t *  een,
Double_t *  fl,
Double_t *  efl,
Double_t &  gain,
Double_t &  off,
Double_t &  egain,
Double_t &  eoff 
)
+
+
+ +

+calculates gain and offset for the set of inflection points

Parameters:
+ + + + + + + + + + +
nscan number of energy scans
en array of energies (nscan long)
een array of errors on energies (nscan long) - can be NULL!
fl array of inflection points (nscan long)
efl array of errors on the inflection points (nscan long)
gain reference to gain resulting from the fit
off reference to offset resulting from the fit
egain reference to error on the gain resulting from the fit
eoff reference to the error on the offset resulting from the fit
+
+
Returns:
graph energy vs inflection point
+ +
+

+ +

+
+ + + + + + + + + +
int energyCalibration::setChargeSharing (int  p = -1  ) 
+
+
+ +

+sets plot flag

Parameters:
+ + +
p plot flag (-1 gets, 0 unsets, >0 plot)
+
+
Returns:
current plot flag
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
void energyCalibration::setFitRange (Double_t  mi,
Double_t  ma 
) [inline]
+
+
+ +

+sets the s-curve fit range

Parameters:
+ + + +
mi minimum of the fit range (-1 is histogram x-min)
ma maximum of the fit range (-1 is histogram x-max)
+
+ +
+

+ +

+
+ + + + + + + + + +
int energyCalibration::setPlotFlag (int  p = -1  )  [inline]
+
+
+ +

+sets plot flag

Parameters:
+ + +
p plot flag (-1 gets, 0 unsets, >0 plot)
+
+
Returns:
current plot flag
+ +
+

+ +

+
+ + + + + + + + + +
int energyCalibration::setScanSign (int  s = 0  )  [inline]
+
+
+ +

+sets scan sign

Parameters:
+ + +
s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets
+
+
Returns:
current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions)
+ +
+

+ +

+
+ + + + + + + + + +
void energyCalibration::setStartParameters (Double_t *  par  ) 
+
+
+ +

+set start parameters for the s-curve function

Parameters:
+ + +
par parameters, -1 sets to auto-calculation par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive
+
+ +
+

+


Member Data Documentation

+ +
+
+ + + + +
Double_t energyCalibration::ampl [private]
+
+
+ +

+start value for the number of photons +

+

+ +

+
+ + + + +
Double_t energyCalibration::bg_offset [private]
+
+
+ +

+start value for the background pedestal +

+

+ +

+
+ + + + +
Double_t energyCalibration::bg_slope [private]
+
+
+ +

+start value for the background slope +

+

+ +

+
+ + + + +
int energyCalibration::cs_flag [private]
+
+
+ +

+0 functions without charge sharing contribution, >0 with charge sharing contribution +

+

+ +

+
+ + + + +
Double_t energyCalibration::cs_slope [private]
+
+
+ +

+start value for the charge sharing slope +

+

+ +

+
+ + + + +
Double_t energyCalibration::fit_max [private]
+
+
+ +

+maximum of the s-curve fitting range, -1 is histogram x-max +

+

+ +

+
+ + + + +
Double_t energyCalibration::fit_min [private]
+
+
+ +

+minimum of the s-curve fitting range, -1 is histogram x-min +

+

+ +

+
+ + + + +
Double_t energyCalibration::flex [private]
+
+
+ +

+start value for the inflection point +

+

+ +

+
+ + + + +
TF1* energyCalibration::fscurve [private]
+
+
+ +

+function with which the s-curve will be fitted +

+

+ +

+
+ + + + +
TF1* energyCalibration::fspectrum [private]
+
+
+ +

+function with which the spectrum will be fitted +

+

+ +

+ +
+ +

+ +

+

+ +

+
+ + + + +
Double_t energyCalibration::noise [private]
+
+
+ +

+start value for the noise +

+

+ +

+
+ + + + +
int energyCalibration::plot_flag [private]
+
+
+ +

+0 does not plot, >0 plots (flags?) +

+

+


The documentation for this class was generated from the following file: +
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibrationFunctions-members.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibrationFunctions-members.html new file mode 100644 index 000000000..6e87b92ca --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibrationFunctions-members.html @@ -0,0 +1,38 @@ + + +Member List + + + + + + +

energyCalibrationFunctions Member List

This is the complete list of members for energyCalibrationFunctions, including all inherited members.

+ + + + + + + + + + + + + +
energyCalibrationFunctions(int s=-1)energyCalibrationFunctions [inline]
erfFuncFluo(Double_t *x, Double_t *par)energyCalibrationFunctions
erfFunction(Double_t *x, Double_t *par)energyCalibrationFunctions
erfFunctionChargeSharing(Double_t *x, Double_t *par)energyCalibrationFunctions
gaussChargeSharing(Double_t *x, Double_t *par)energyCalibrationFunctions
kth_smallest(int *a, int n, int k)energyCalibrationFunctions [static]
median(float *x, int n)energyCalibrationFunctions [static]
quick_select(int arr[], int n)energyCalibrationFunctions [static]
scurve(Double_t *x, Double_t *par)energyCalibrationFunctions
scurveFluo(Double_t *x, Double_t *par)energyCalibrationFunctions
setScanSign(int s=0)energyCalibrationFunctions [inline]
signenergyCalibrationFunctions [private]
spectrum(Double_t *x, Double_t *par)energyCalibrationFunctions


Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibrationFunctions.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibrationFunctions.html new file mode 100644 index 000000000..2a0dfd405 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classenergyCalibrationFunctions.html @@ -0,0 +1,428 @@ + + +energyCalibrationFunctions Class Reference + + + + + + +

energyCalibrationFunctions Class Reference

Energy calibration functions. +More... +

+#include <energyCalibration.h> +

+List of all members. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Public Member Functions

 energyCalibrationFunctions (int s=-1)
int setScanSign (int s=0)
Double_t gaussChargeSharing (Double_t *x, Double_t *par)
Double_t erfFunction (Double_t *x, Double_t *par)
Double_t erfFunctionChargeSharing (Double_t *x, Double_t *par)
Double_t erfFuncFluo (Double_t *x, Double_t *par)
Double_t spectrum (Double_t *x, Double_t *par)
Double_t scurve (Double_t *x, Double_t *par)
Double_t scurveFluo (Double_t *x, Double_t *par)

Static Public Member Functions

static float median (float *x, int n)
static int quick_select (int arr[], int n)
static int kth_smallest (int *a, int n, int k)

Private Attributes

int sign
+


Detailed Description

+Energy calibration functions. +

+class containing all the possible energy calibration functions (scurves with and without charge sharing, gaussian spectrum with and without charge sharing, possibility of chosing the sign of the X-axis) +

+


Constructor & Destructor Documentation

+ +
+
+ + + + + + + + + +
energyCalibrationFunctions::energyCalibrationFunctions (int  s = -1  )  [inline]
+
+
+ +

+ +

+

+


Member Function Documentation

+ +
+
+ + + + + + + + + + + + + + + + + + +
Double_t energyCalibrationFunctions::erfFuncFluo (Double_t *  x,
Double_t *  par 
)
+
+
+ +

+Double Erf function with charge sharing slope par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point of the first energy par[3] is the RMS of the first energy par[4] is the amplitude of the first energy par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) par[6] is the inflection point of the second energy par[7] is the RMS of the second energy par[8] is the amplitude of the second energy par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
Double_t energyCalibrationFunctions::erfFunction (Double_t *  x,
Double_t *  par 
)
+
+
+ +

+Basic erf function par[0] is the inflection point par[1] is the RMS par[2] is the amplitude +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
Double_t energyCalibrationFunctions::erfFunctionChargeSharing (Double_t *  x,
Double_t *  par 
)
+
+
+ +

+Erf function with charge sharing slope par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
Double_t energyCalibrationFunctions::gaussChargeSharing (Double_t *  x,
Double_t *  par 
)
+
+
+ +

+Gaussian Function with charge sharing pedestal par[0] is the absolute height of the background pedestal par[1] is the slope of the background pedestal par[2] is the gaussian peak position par[3] is the RMS of the gaussian (and of the pedestal) par[4] is the height of the function par[5] is the fractional height of the charge sharing pedestal (scales with par[3]) +

+

+ +

+
+ + + + + + + + + + + + + + + + + + + + + + + + +
static int energyCalibrationFunctions::kth_smallest (int *  a,
int  n,
int  k 
) [static]
+
+
+ +

+Calculates the median of an array of n elements (swaps the arrays!) +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
static float energyCalibrationFunctions::median (float *  x,
int  n 
) [static]
+
+
+ +

+Calculates the median of an array of n elements +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
static int energyCalibrationFunctions::quick_select (int  arr[],
int  n 
) [static]
+
+
+ +

+Calculates the median of an array of n elements (swaps the arrays!) +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
Double_t energyCalibrationFunctions::scurve (Double_t *  x,
Double_t *  par 
)
+
+
+ +

+Erf function with charge sharing slope with the correct scan sign par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) +

+

+ +

+
+ + + + + + + + + + + + + + + + + + +
Double_t energyCalibrationFunctions::scurveFluo (Double_t *  x,
Double_t *  par 
)
+
+
+ +

+Double Erf function with charge sharing slope par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point of the first energy par[3] is the RMS of the first energy par[4] is the amplitude of the first energy par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) par[6] is the inflection point of the second energy par[7] is the RMS of the second energy par[8] is the amplitude of the second energy par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) +

+

+ +

+
+ + + + + + + + + +
int energyCalibrationFunctions::setScanSign (int  s = 0  )  [inline]
+
+
+ +

+sets scan sign

Parameters:
+ + +
s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets
+
+
Returns:
current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions)
+ +
+

+ +

+
+ + + + + + + + + + + + + + + + + + +
Double_t energyCalibrationFunctions::spectrum (Double_t *  x,
Double_t *  par 
)
+
+
+ +

+static function Gaussian with charge sharing pedestal with the correct scan sign par[0] is the absolute height of the background pedestal par[1] is the fractional height of the charge sharing pedestal (scales with par[3] par[2] is the gaussian peak position par[3] is the RMS of the gaussian (and of the pedestal) par[4] is the height of the function +

+

+


Member Data Documentation

+ +
+
+ + + + +
int energyCalibrationFunctions::sign [private]
+
+
+ +

+ +

+

+


The documentation for this class was generated from the following file: +
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classes.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classes.html new file mode 100644 index 000000000..4cc7a4ddd --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/classes.html @@ -0,0 +1,69 @@ + + + + + +Alphabetical List + + + + + + + + + +
+

Class Index

+ +
  E  
+
energyCalibration   energyCalibrationFunctions   
+
+ + + + +
+ +
+ +
Generated on Tue Mar 20 17:21:14 2012 by  + +doxygen 1.6.0
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/doxygen.css b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/doxygen.css new file mode 100644 index 000000000..5d583694e --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/doxygen.css @@ -0,0 +1,358 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +BODY,TD { + font-size: 90%; +} +H1 { + text-align: center; + font-size: 160%; +} +H2 { + font-size: 120%; +} +H3 { + font-size: 100%; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.navtab { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +TD.navtab { + font-size: 70%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace, fixed; + font-size: 95%; +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } + +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 90% } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #e8eef2; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #e8eef2; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 80%; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 80%; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 80%; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #e8eef2; +} +TD.tiny { font-size: 75%; +} +a { + color: #1A41A8; +} +a:visited { + color: #2A3798; +} +.dirtab { padding: 4px; + border-collapse: collapse; + border: 1px solid #84b0c7; +} +TH.dirtab { background: #e8eef2; + font-weight: bold; +} +HR { height: 1px; + border: none; + border-top: 1px solid black; +} + +/* Style for detailed member documentation */ +.memtemplate { + font-size: 80%; + color: #606060; + font-weight: normal; +} +.memnav { + background-color: #e8eef2; + border: 1px solid #84b0c7; + text-align: center; + margin: 2px; + margin-right: 15px; + padding: 2px; +} +.memitem { + padding: 4px; + background-color: #eef3f5; + border-width: 1px; + border-style: solid; + border-color: #dedeee; + -moz-border-radius: 8px 8px 8px 8px; +} +.memname { + white-space: nowrap; + font-weight: bold; +} +.memdoc{ + padding-left: 10px; +} +.memproto { + background-color: #d5e1e8; + width: 100%; + border-width: 1px; + border-style: solid; + border-color: #84b0c7; + font-weight: bold; + -moz-border-radius: 8px 8px 8px 8px; +} +.paramkey { + text-align: right; +} +.paramtype { + white-space: nowrap; +} +.paramname { + color: #602020; + font-style: italic; +} +/* End Styling for detailed member documentation */ + +/* for the tree view */ +.ftvtree { + font-family: sans-serif; + margin:0.5em; +} +.directory { font-size: 9pt; font-weight: bold; } +.directory h3 { margin: 0px; margin-top: 1em; font-size: 11pt; } +.directory > h3 { margin-top: 0; } +.directory p { margin: 0px; white-space: nowrap; } +.directory div { display: none; margin: 0px; } +.directory img { vertical-align: -30%; } + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/doxygen.png b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/doxygen.png new file mode 100644 index 000000000..f0a274bba Binary files /dev/null and b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/doxygen.png differ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h-source.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h-source.html new file mode 100644 index 000000000..64e8c0558 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h-source.html @@ -0,0 +1,164 @@ + + +energyCalibration.h Source File + + + + + + +

energyCalibration.h

Go to the documentation of this file.
00001 
+00002 #ifndef ENERGYCALIBRATION_H
+00003 #define ENERGYCALIBRATION_H
+00004 
+00005 #include <TROOT.h>
+00006 #include <TF1.h>
+00007 
+00008 using namespace std;
+00009 
+00010 class TH1F;
+00011 class TGraphErrors;
+00012 
+00013 
+00014 
+00015 
+00016 
+00017 const float conven=1000./3.6; 
+00018 const float el=1.67E-4; 
+00050 class energyCalibrationFunctions {
+00051 
+00052  public:
+00053   
+00054   energyCalibrationFunctions(int s=-1) {setScanSign(s);};
+00055   
+00060   int setScanSign(int s=0) {if (s==1 || s==-1) sign=s; return sign;};;
+00061   
+00062 
+00072   Double_t gaussChargeSharing(Double_t *x, Double_t *par);
+00073 
+00080 Double_t erfFunction(Double_t *x, Double_t *par) ;
+00081 
+00090 Double_t erfFunctionChargeSharing(Double_t *x, Double_t *par);
+00091   
+00105 Double_t erfFuncFluo(Double_t *x, Double_t *par);
+00106 
+00107 
+00109   static float median(float *x, int n);
+00111   static int quick_select(int arr[], int n);
+00113   static int kth_smallest(int *a, int n, int k);
+00114 
+00115   
+00124   Double_t spectrum(Double_t *x, Double_t *par);
+00125 
+00126 
+00135   Double_t scurve(Double_t *x, Double_t *par);
+00136 
+00137 
+00138 
+00151   Double_t scurveFluo(Double_t *x, Double_t *par);
+00152 
+00153 
+00154  private:
+00155   int sign;
+00156     
+00157 
+00158 };
+00159 
+00165 class energyCalibration  {
+00166 
+00167 
+00168  public:
+00172   energyCalibration();
+00173     
+00177   ~energyCalibration();
+00178     
+00183   int setPlotFlag(int p=-1) {if (p>=0) plot_flag=p; return plot_flag;};
+00184 
+00189   int setScanSign(int s=0) {return funcs->setScanSign(s);};
+00190   
+00195   int setChargeSharing(int p=-1);
+00196   
+00201   void setFitRange(Double_t mi, Double_t ma){fit_min=mi; fit_max=ma;};
+00202 
+00207   void getFitRange(Double_t &mi, Double_t &ma){mi=fit_min; ma=fit_max;};
+00208 
+00209 
+00219   void setStartParameters(Double_t *par);
+00220   
+00230   void getStartParameters(Double_t *par);
+00231 
+00239   TF1 *fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar);
+00240 
+00241 
+00249   TF1 *fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar);
+00250 
+00251 
+00265   TGraphErrors* linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff);  
+00266 
+00279   TGraphErrors* calibrateScurves(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 1);};    
+00280 
+00293   TGraphErrors* calibrateSpectra(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 0);};  
+00294 
+00295 
+00296 
+00297  private:
+00309   TGraphErrors* calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral=1);  
+00310 
+00311 
+00319   void initFitFunction(TF1 *fun, TH1 *h1);
+00320 
+00321 
+00330   TF1 *fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar);  
+00331 
+00332 
+00333   int plot_flag; 
+00335   int cs_flag; 
+00337   Double_t fit_min; 
+00338   Double_t fit_max; 
+00340   Double_t bg_offset; 
+00341   Double_t bg_slope; 
+00342   Double_t flex; 
+00343   Double_t noise; 
+00344   Double_t ampl; 
+00345   Double_t cs_slope; 
+00347   energyCalibrationFunctions *funcs;
+00348 
+00349   TF1 *fscurve; 
+00351   TF1 *fspectrum; 
+00354 };
+00355 
+00356 #endif
+00357 
+00358 
+00359 
+00360 
+00361 
+00362 
+00363 
+00364 
+00365 
+00366 
+00367 
+00368 
+00369 
+00370 
+00371 
+00372 
+00373 
+00374 
+00375 
+

Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h.html new file mode 100644 index 000000000..a25ed2496 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h.html @@ -0,0 +1,76 @@ + + +energyCalibration.h File Reference + + + + + + +

energyCalibration.h File Reference

#include <TROOT.h>
+#include <TF1.h>
+ +

+Go to the source code of this file. + + + + + + + + + + + + + + + +

Namespaces

namespace  std

Classes

class  energyCalibrationFunctions
 Energy calibration functions. More...
class  energyCalibration

Variables

const float conven = 1000./3.6
const float el = 1.67E-4
+


Variable Documentation

+ +
+
+ + + + +
const float conven = 1000./3.6
+
+
+ +

+electrons/keV +

+

+ +

+
+ + + + +
const float el = 1.67E-4
+
+
+ +

+electron charge in fC +

+

+


Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h_source.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h_source.html new file mode 100644 index 000000000..fc14ca380 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/energyCalibration_8h_source.html @@ -0,0 +1,190 @@ + + + + + +energyCalibration.h Source File + + + + + + + + + + + + + +
+ +
+ +
Generated on Tue Mar 20 17:21:14 2012 by  + +doxygen 1.6.0
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/files.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/files.html new file mode 100644 index 000000000..a0ea14100 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/files.html @@ -0,0 +1,27 @@ + + +File Index + + + + + + +

File List

Here is a list of all files with brief descriptions: + +
energyCalibration.h [code]
+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions.html new file mode 100644 index 000000000..2dc86e2c0 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions.html @@ -0,0 +1,126 @@ + + +Class Members + + + + + + +
+ +
+
+ +
+ +

+Here is a list of all class members with links to the classes they belong to: +

+

- a -

+

- b -

+

- c -

+

- e -

+

- f -

+

- g -

+

- i -

+

- k -

+

- l -

+

- m -

+

- n -

+

- p -

+

- q -

+

- s -

+

- ~ -

+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions_func.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions_func.html new file mode 100644 index 000000000..a82a14a3a --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions_func.html @@ -0,0 +1,63 @@ + + +Class Members - Functions + + + + + + +
+ +
+  +

+

+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions_vars.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions_vars.html new file mode 100644 index 000000000..3eb5ab2c3 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/functions_vars.html @@ -0,0 +1,49 @@ + + +Class Members - Variables + + + + + + +
+ +
+  +

+

+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/globals.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/globals.html new file mode 100644 index 000000000..6867e7583 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/globals.html @@ -0,0 +1,36 @@ + + +Class Members + + + + + + +
+ +
+Here is a list of all file members with links to the files they belong to: +

+

+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/globals_vars.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/globals_vars.html new file mode 100644 index 000000000..efb3d3424 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/globals_vars.html @@ -0,0 +1,36 @@ + + +Class Members + + + + + + +
+ +
+  +

+

+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/index.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/index.html new file mode 100644 index 000000000..8e6122ad2 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/index.html @@ -0,0 +1,25 @@ + + +Common Root library for SLS detectors data analysis + + + + + +

Common Root library for SLS detectors data analysis

+

+

+Introduction

+We know very well s-curves etc. but at the end everybody uses different functions ;-).

+Motivation

+It would be greate to use everybody the same functions...
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/installdox b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/installdox new file mode 100755 index 000000000..9b89fe025 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/installdox @@ -0,0 +1,117 @@ +#!/usr/bin/perl + +%subst = ( ); +$quiet = 0; + +if (open(F,"search.cfg")) +{ + $_= ; s/[ \t\n]*$//g ; $subst{"_doc"} = $_; + $_= ; s/[ \t\n]*$//g ; $subst{"_cgi"} = $_; +} + +while ( @ARGV ) { + $_ = shift @ARGV; + if ( s/^-// ) { + if ( /^l(.*)/ ) { + $v = ($1 eq "") ? shift @ARGV : $1; + ($v =~ /\/$/) || ($v .= "/"); + $_ = $v; + if ( /(.+)\@(.+)/ ) { + if ( exists $subst{$1} ) { + $subst{$1} = $2; + } else { + print STDERR "Unknown tag file $1 given with option -l\n"; + &usage(); + } + } else { + print STDERR "Argument $_ is invalid for option -l\n"; + &usage(); + } + } + elsif ( /^q/ ) { + $quiet = 1; + } + elsif ( /^\?|^h/ ) { + &usage(); + } + else { + print STDERR "Illegal option -$_\n"; + &usage(); + } + } + else { + push (@files, $_ ); + } +} + +foreach $sub (keys %subst) +{ + if ( $subst{$sub} eq "" ) + { + print STDERR "No substitute given for tag file `$sub'\n"; + &usage(); + } + elsif ( ! $quiet && $sub ne "_doc" && $sub ne "_cgi" ) + { + print "Substituting $subst{$sub} for each occurence of tag file $sub\n"; + } +} + +if ( ! @files ) { + if (opendir(D,".")) { + foreach $file ( readdir(D) ) { + $match = ".html"; + next if ( $file =~ /^\.\.?$/ ); + ($file =~ /$match/) && (push @files, $file); + ($file =~ "tree.js") && (push @files, $file); + } + closedir(D); + } +} + +if ( ! @files ) { + print STDERR "Warning: No input files given and none found!\n"; +} + +foreach $f (@files) +{ + if ( ! $quiet ) { + print "Editing: $f...\n"; + } + $oldf = $f; + $f .= ".bak"; + unless (rename $oldf,$f) { + print STDERR "Error: cannot rename file $oldf\n"; + exit 1; + } + if (open(F,"<$f")) { + unless (open(G,">$oldf")) { + print STDERR "Error: opening file $oldf for writing\n"; + exit 1; + } + if ($oldf ne "tree.js") { + while () { + s/doxygen\=\"([^ \"\:\t\>\<]*)\:([^ \"\t\>\<]*)\" (href|src)=\"\2/doxygen\=\"$1:$subst{$1}\" \3=\"$subst{$1}/g; + print G "$_"; + } + } + else { + while () { + s/\"([^ \"\:\t\>\<]*)\:([^ \"\t\>\<]*)\", \"\2/\"$1:$subst{$1}\" ,\"$subst{$1}/g; + print G "$_"; + } + } + } + else { + print STDERR "Warning file $f does not exist\n"; + } + unlink $f; +} + +sub usage { + print STDERR "Usage: installdox [options] [html-file [html-file ...]]\n"; + print STDERR "Options:\n"; + print STDERR " -l tagfile\@linkName tag file + URL or directory \n"; + print STDERR " -q Quiet mode\n\n"; + exit 1; +} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/namespaces.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/namespaces.html new file mode 100644 index 000000000..f3343cb4d --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/namespaces.html @@ -0,0 +1,22 @@ + + +Namespace Index + + + + + +

Namespace List

Here is a list of all namespaces with brief descriptions: + +
std
+
Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/namespacestd.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/namespacestd.html new file mode 100644 index 000000000..7f96b5d3c --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/namespacestd.html @@ -0,0 +1,24 @@ + + +std Namespace Reference + + + + + +

std Namespace Reference

+

+ + +
+


Generated on Tue Mar 27 16:32:29 2012 by  + +doxygen 1.4.7
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_61.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_61.html new file mode 100644 index 000000000..dbc525140 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_61.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ ampl + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_62.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_62.html new file mode 100644 index 000000000..1587baf85 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_62.html @@ -0,0 +1,31 @@ + + + + + + +
+
Loading...
+
+
+ bg_offset + energyCalibration +
+
+
+
+ bg_slope + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_63.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_63.html new file mode 100644 index 000000000..9f05baa3d --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_63.html @@ -0,0 +1,37 @@ + + + + + + +
+
Loading...
+
+
+ calibrate + energyCalibration +
+
+
+
+ conven + energyCalibration.h +
+
+
+
+ cs_slope + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_65.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_65.html new file mode 100644 index 000000000..d8cc513ff --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_65.html @@ -0,0 +1,66 @@ + + + + + + +
+
Loading...
+
+
+ el + energyCalibration.h +
+
+ + + +
+
+ erfFuncFluo + energyCalibrationFunctions +
+
+
+
+ erfFunction + energyCalibrationFunctions +
+
+
+
+ erfFunctionChargeSharing + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_66.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_66.html new file mode 100644 index 000000000..bd1572f3b --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_66.html @@ -0,0 +1,55 @@ + + + + + + +
+
Loading...
+
+
+ fit_max + energyCalibration +
+
+
+
+ fit_min + energyCalibration +
+
+
+
+ fitSCurve + energyCalibration +
+
+
+
+ flex + energyCalibration +
+
+
+
+ fscurve + energyCalibration +
+
+
+
+ funcs + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_67.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_67.html new file mode 100644 index 000000000..a5fbc8718 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_67.html @@ -0,0 +1,37 @@ + + + + + + +
+
Loading...
+
+
+ gaussChargeSharing + energyCalibrationFunctions +
+
+
+
+ getFitRange + energyCalibration +
+
+
+
+ getStartParameters + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6b.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6b.html new file mode 100644 index 000000000..40cf25174 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6b.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ kth_smallest + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6c.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6c.html new file mode 100644 index 000000000..6ddf1903c --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6c.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ linearCalibration + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6d.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6d.html new file mode 100644 index 000000000..d7612fe26 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6d.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ median + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6e.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6e.html new file mode 100644 index 000000000..7ee4200c2 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_6e.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ noise + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_70.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_70.html new file mode 100644 index 000000000..402fa63cb --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_70.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ plot_flag + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_71.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_71.html new file mode 100644 index 000000000..0c68aa1c7 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_71.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ quick_select + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_73.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_73.html new file mode 100644 index 000000000..52cede178 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_73.html @@ -0,0 +1,70 @@ + + + + + + +
+
Loading...
+
+
+ scurve + energyCalibrationFunctions +
+
+
+
+ scurveFluo + energyCalibrationFunctions +
+
+
+
+ setFitRange + energyCalibration +
+
+
+
+ setPlotFlag + energyCalibration +
+
+ +
+
+ setStartParameters + energyCalibration +
+
+
+
+ sign + energyCalibrationFunctions +
+
+
+
+ spectrum + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_7e.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_7e.html new file mode 100644 index 000000000..22b73eeab --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/all_7e.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ ~energyCalibration + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/classes_65.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/classes_65.html new file mode 100644 index 000000000..0cd426302 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/classes_65.html @@ -0,0 +1,29 @@ + + + + + + +
+
Loading...
+ + +
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/close.png b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/close.png new file mode 100644 index 000000000..9342d3dfe Binary files /dev/null and b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/close.png differ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/files_65.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/files_65.html new file mode 100644 index 000000000..72afed66a --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/files_65.html @@ -0,0 +1,24 @@ + + + + + + +
+
Loading...
+ +
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_63.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_63.html new file mode 100644 index 000000000..dbde61421 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_63.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ calibrate + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_65.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_65.html new file mode 100644 index 000000000..4aac8500d --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_65.html @@ -0,0 +1,49 @@ + + + + + + +
+
Loading...
+
+
+ energyCalibration + energyCalibration +
+
+
+
+ energyCalibrationFunctions + energyCalibrationFunctions +
+
+
+
+ erfFuncFluo + energyCalibrationFunctions +
+
+
+
+ erfFunction + energyCalibrationFunctions +
+
+
+
+ erfFunctionChargeSharing + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_66.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_66.html new file mode 100644 index 000000000..e1b9f157c --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_66.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ fitSCurve + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_67.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_67.html new file mode 100644 index 000000000..a5fbc8718 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_67.html @@ -0,0 +1,37 @@ + + + + + + +
+
Loading...
+
+
+ gaussChargeSharing + energyCalibrationFunctions +
+
+
+
+ getFitRange + energyCalibration +
+
+
+
+ getStartParameters + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6b.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6b.html new file mode 100644 index 000000000..40cf25174 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6b.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ kth_smallest + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6c.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6c.html new file mode 100644 index 000000000..6ddf1903c --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6c.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ linearCalibration + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6d.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6d.html new file mode 100644 index 000000000..d7612fe26 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_6d.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ median + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_71.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_71.html new file mode 100644 index 000000000..0c68aa1c7 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_71.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ quick_select + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_73.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_73.html new file mode 100644 index 000000000..4daf9bb0f --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_73.html @@ -0,0 +1,64 @@ + + + + + + +
+
Loading...
+
+
+ scurve + energyCalibrationFunctions +
+
+
+
+ scurveFluo + energyCalibrationFunctions +
+
+
+
+ setFitRange + energyCalibration +
+
+
+
+ setPlotFlag + energyCalibration +
+
+ +
+
+ setStartParameters + energyCalibration +
+
+
+
+ spectrum + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_7e.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_7e.html new file mode 100644 index 000000000..22b73eeab --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/functions_7e.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ ~energyCalibration + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/nomatches.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/nomatches.html new file mode 100644 index 000000000..fd9248fe3 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/nomatches.html @@ -0,0 +1,11 @@ + + + + + + +
+
No Matches
+
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.css b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.css new file mode 100644 index 000000000..d263b9724 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.css @@ -0,0 +1,198 @@ +/*---------------- Search Box */ + +#MSearchBox { + padding: 0px; + margin: 0px; + border: none; + border: 1px solid #84B0C7; + white-space: nowrap; + -moz-border-radius: 8px; + -webkit-border-top-left-radius: 8px; + -webkit-border-top-right-radius: 8px; + -webkit-border-bottom-left-radius: 8px; + -webkit-border-bottom-right-radius: 8px; +} +#MSearchField { + font: 9pt Arial, Verdana, sans-serif; + color: #999999; + background-color: #FFFFFF; + font-style: normal; + cursor: text; + padding: 1px 1px; + margin: 0px 6px 0px 0px; + border: none; + outline: none; + vertical-align: middle; +} +.MSearchBoxActive #MSearchField { + color: #000000; +} +#MSearchSelect { + float : none; + display : inline; + background : none; + font: 9pt Verdana, sans-serif; + border: none; + margin: 0px 0px 0px 6px; + vertical-align: middle; + padding: 0px 0px; +} + +#MSearchClose { + float : none; + display : none; + background : none; + border: none; + margin: 0px 4px 0px 0px; + padding: 0px 0px; + outline: none; +} + +#MSearchCloseImg { + vertical-align: middle; +} + +.MSearchBoxLeft { + display: block; + text-align: left; + float: left; + margin-left: 6px; +} +.MSearchBoxRight { + display: block; + float: right; + text-align: right; + margin-right: 6px; +} +.MSearchBoxSpacer { + font-size: 0px; + clear: both; +} +.MSearchBoxRow { + font-size: 0px; + clear: both; +} + +/*---------------- Search filter selection */ + +#MSearchSelectWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #A0A0A0; + background-color: #FAFAFA; + z-index: 1; + padding-top: 4px; + padding-bottom: 4px; + -moz-border-radius: 4px; + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15); + } +.SelectItem { + font: 8pt Arial, Verdana, sans-serif; + padding-left: 2px; + padding-right: 12px; + border: 0px; +} +span.SelectionMark { + margin-right: 4px; + font-family: monospace; + outline-style: none; + text-decoration: none; +} +a.SelectItem { + display: block; + outline-style: none; + color: #000000; + text-decoration: none; + padding-left: 6px; + padding-right: 12px; +} +a.SelectItem:focus, +a.SelectItem:active { + color: #000000; + outline-style: none; + text-decoration: none; +} +a.SelectItem:hover { + color: #FFFFFF; + background-color: #2A50E4; + outline-style: none; + text-decoration: none; + cursor: pointer; + display: block; +} + +/*---------------- Search results window */ + +iframe#MSearchResults { + width: 60ex; + height: 15em; + } +#MSearchResultsWindow { + display: none; + position: absolute; + left: 0; top: 0; + border: 1px solid #000000; + background-color: #EEF3F5; + } + +/* ----------------------------------- */ + + +#SRIndex { + clear:both; + padding-bottom: 15px; +} + +.SREntry { + font-size: 10pt; + padding-left: 1ex; +} +.SRPage .SREntry { + font-size: 8pt; + padding: 1px 5px; +} +body.SRPage { + margin: 5px 2px; +} + +.SRChildren { + padding-left: 3ex; padding-bottom: .5em +} +.SRPage .SRChildren { + display: none; +} +.SRSymbol { + font-weight: bold; color: #153788; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRScope { + display: block; + color: #153788; + font-family: Arial, Verdana, sans-serif; + text-decoration: none; + outline: none; +} + +a.SRSymbol:focus, a.SRSymbol:active, +a.SRScope:focus, a.SRScope:active { + text-decoration: underline; +} + +.SRPage .SRStatus { + padding: 2px 5px; + font-size: 8pt; + font-style: italic; +} + +.SRResult { + display: none; +} + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.js b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.js new file mode 100644 index 000000000..4fadd5247 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.js @@ -0,0 +1,734 @@ +// Search script generated by doxygen +// Copyright (C) 2009 by Dimitri van Heesch. + +// The code in this file is loosly based on main.js, part of Natural Docs, +// which is Copyright (C) 2003-2008 Greg Valure +// Natural Docs is licensed under the GPL. + +var indexSectionsWithContent = +{ + 0: "000000000000000000000000000000000000000000000000000000000000000001110111000111101101000000000010", + 1: "000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", + 2: "000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000", + 3: "000000000000000000000000000000000000000000000000000000000000000000010111000111000101000000000010", + 4: "000000000000000000000000000000000000000000000000000000000000000001110110000000101001000000000000" +}; + +var indexSectionNames = +{ + 0: "all", + 1: "classes", + 2: "files", + 3: "functions", + 4: "variables" +}; + +function convertToId(search) +{ + var result = ''; + for (i=0;i do a search + { + this.Search(); + } + } + + this.OnSearchSelectKey = function(evt) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==40 && this.searchIndex0) // Up + { + this.searchIndex--; + this.OnSelectItem(this.searchIndex); + } + else if (e.keyCode==13 || e.keyCode==27) + { + this.OnSelectItem(this.searchIndex); + this.CloseSelectionWindow(); + this.DOMSearchField().focus(); + } + return false; + } + + // --------- Actions + + // Closes the results window. + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = 'none'; + this.DOMSearchClose().style.display = 'none'; + this.Activate(false); + } + + this.CloseSelectionWindow = function() + { + this.DOMSearchSelectWindow().style.display = 'none'; + } + + // Performs a search. + this.Search = function() + { + this.keyTimeout = 0; + + // strip leading whitespace + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + + var code = searchValue.toLowerCase().charCodeAt(0); + var hexCode; + if (code<16) + { + hexCode="0"+code.toString(16); + } + else + { + hexCode=code.toString(16); + } + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + if (indexSectionsWithContent[this.searchIndex].charAt(code-32) == '1') + { + resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else // nothing available for this search term + { + resultsPage = this.resultsPath + '/nomatches.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + } + + window.frames.MSearchResults.location.href = resultsPageWithSearch; + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (domPopupSearchResultsWindow.style.display!='block') + { + var domSearchBox = this.DOMSearchBox(); + this.DOMSearchClose().style.display = 'inline'; + if (this.insideFrame) + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + domPopupSearchResultsWindow.style.position = 'relative'; + domPopupSearchResultsWindow.style.display = 'block'; + var width = document.body.clientWidth - 8; // the -8 is for IE :-( + domPopupSearchResultsWindow.style.width = width + 'px'; + domPopupSearchResults.style.width = width + 'px'; + } + else + { + var domPopupSearchResults = this.DOMPopupSearchResults(); + var left = getXPos(domSearchBox) + domSearchBox.offsetWidth; + var top = getYPos(domSearchBox) + domSearchBox.offsetHeight + 1; + domPopupSearchResultsWindow.style.display = 'block'; + left -= domPopupSearchResults.offsetWidth; + domPopupSearchResultsWindow.style.top = top + 'px'; + domPopupSearchResultsWindow.style.left = left + 'px'; + } + } + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + } + + // -------- Activation Functions + + // Activates or deactivates the search panel, resetting things to + // their default values if necessary. + this.Activate = function(isActive) + { + if (isActive || // open it + this.DOMPopupSearchResultsWindow().style.display == 'block' + ) + { + this.DOMSearchBox().className = 'MSearchBoxActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == this.searchLabel) // clear "Search" term upon entry + { + searchField.value = ''; + this.searchActive = true; + } + } + else if (!isActive) // directly remove the panel + { + this.DOMSearchBox().className = 'MSearchBoxInactive'; + this.DOMSearchField().value = this.searchLabel; + this.searchActive = false; + this.lastSearchValue = '' + this.lastResultsPage = ''; + } + } +} + +// ----------------------------------------------------------------------- + +// The class that handles everything on the search results page. +function SearchResults(name) +{ + // The number of matches from the last run of . + this.lastMatchCount = 0; + this.lastKey = 0; + this.repeatOn = false; + + // Toggles the visibility of the passed element ID. + this.FindChildElement = function(id) + { + var parentElement = document.getElementById(id); + var element = parentElement.firstChild; + + while (element && element!=parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'SRChildren') + { + return element; + } + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { + element = element.firstChild; + } + else if (element.nextSibling) + { + element = element.nextSibling; + } + else + { + do + { + element = element.parentNode; + } + while (element && element!=parentElement && !element.nextSibling); + + if (element && element!=parentElement) + { + element = element.nextSibling; + } + } + } + } + + this.Toggle = function(id) + { + var element = this.FindChildElement(id); + if (element) + { + if (element.style.display == 'block') + { + element.style.display = 'none'; + } + else + { + element.style.display = 'block'; + } + } + } + + // Searches for the passed string. If there is no parameter, + // it takes it from the URL query. + // + // Always returns true, since other documents may try to call it + // and that may or may not be possible. + this.Search = function(search) + { + if (!search) // get search word from URL + { + search = window.location.search; + search = search.substring(1); // Remove the leading '?' + search = unescape(search); + } + + search = search.replace(/^ +/, ""); // strip leading spaces + search = search.replace(/ +$/, ""); // strip trailing spaces + search = search.toLowerCase(); + search = convertToId(search); + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_' + + if (search.length<=rowMatchName.length && + rowMatchName.substr(0, search.length)==search) + { + row.style.display = 'block'; + matches++; + } + else + { + row.style.display = 'none'; + } + } + i++; + } + document.getElementById("Searching").style.display='none'; + if (matches == 0) // no results + { + document.getElementById("NoMatches").style.display='block'; + } + else // at least one result + { + document.getElementById("NoMatches").style.display='none'; + } + this.lastMatchCount = matches; + return true; + } + + // return the first item with index index or higher that is visible + this.NavNext = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index++; + } + return focusItem; + } + + this.NavPrev = function(index) + { + var focusItem; + while (1) + { + var focusName = 'Item'+index; + focusItem = document.getElementById(focusName); + if (focusItem && focusItem.parentNode.parentNode.style.display=='block') + { + break; + } + else if (!focusItem) // last element + { + break; + } + focusItem=null; + index--; + } + return focusItem; + } + + this.ProcessKeys = function(e) + { + if (e.type == "keydown") + { + this.repeatOn = false; + this.lastKey = e.keyCode; + } + else if (e.type == "keypress") + { + if (!this.repeatOn) + { + if (this.lastKey) this.repeatOn = true; + return false; // ignore first keypress after keydown + } + } + else if (e.type == "keyup") + { + this.lastKey = 0; + this.repeatOn = false; + } + return this.lastKey!=0; + } + + this.Nav = function(evt,itemIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + var newIndex = itemIndex-1; + var focusItem = this.NavPrev(newIndex); + if (focusItem) + { + var child = this.FindChildElement(focusItem.parentNode.parentNode.id); + if (child && child.style.display == 'block') // children visible + { + var n=0; + var tmpElem; + while (1) // search for last child + { + tmpElem = document.getElementById('Item'+newIndex+'_c'+n); + if (tmpElem) + { + focusItem = tmpElem; + } + else // found it! + { + break; + } + n++; + } + } + } + if (focusItem) + { + focusItem.focus(); + } + else // return focus to search field + { + parent.document.getElementById("MSearchField").focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = itemIndex+1; + var focusItem; + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem && elem.style.display == 'block') // children visible + { + focusItem = document.getElementById('Item'+itemIndex+'_c0'); + } + if (!focusItem) focusItem = this.NavNext(newIndex); + if (focusItem) focusItem.focus(); + } + else if (this.lastKey==39) // Right + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'block'; + } + else if (this.lastKey==37) // Left + { + var item = document.getElementById('Item'+itemIndex); + var elem = this.FindChildElement(item.parentNode.parentNode.id); + if (elem) elem.style.display = 'none'; + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } + + this.NavChild = function(evt,itemIndex,childIndex) + { + var e = (evt) ? evt : window.event; // for IE + if (e.keyCode==13) return true; + if (!this.ProcessKeys(e)) return false; + + if (this.lastKey==38) // Up + { + if (childIndex>0) + { + var newIndex = childIndex-1; + document.getElementById('Item'+itemIndex+'_c'+newIndex).focus(); + } + else // already at first child, jump to parent + { + document.getElementById('Item'+itemIndex).focus(); + } + } + else if (this.lastKey==40) // Down + { + var newIndex = childIndex+1; + var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex); + if (!elem) // last child, jump to parent next parent + { + elem = this.NavNext(itemIndex+1); + } + if (elem) + { + elem.focus(); + } + } + else if (this.lastKey==27) // Escape + { + parent.searchBox.CloseResultsWindow(); + parent.document.getElementById("MSearchField").focus(); + } + else if (this.lastKey==13) // Enter + { + return true; + } + return false; + } +} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.png b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.png new file mode 100644 index 000000000..9dd2396db Binary files /dev/null and b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/search.png differ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_61.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_61.html new file mode 100644 index 000000000..dbc525140 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_61.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ ampl + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_62.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_62.html new file mode 100644 index 000000000..1587baf85 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_62.html @@ -0,0 +1,31 @@ + + + + + + +
+
Loading...
+
+
+ bg_offset + energyCalibration +
+
+
+
+ bg_slope + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_63.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_63.html new file mode 100644 index 000000000..6a2de4531 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_63.html @@ -0,0 +1,31 @@ + + + + + + +
+
Loading...
+
+
+ conven + energyCalibration.h +
+
+
+
+ cs_slope + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_65.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_65.html new file mode 100644 index 000000000..b199804b0 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_65.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ el + energyCalibration.h +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_66.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_66.html new file mode 100644 index 000000000..d0ae5492f --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_66.html @@ -0,0 +1,49 @@ + + + + + + +
+
Loading...
+
+
+ fit_max + energyCalibration +
+
+
+
+ fit_min + energyCalibration +
+
+
+
+ flex + energyCalibration +
+
+
+
+ fscurve + energyCalibration +
+
+
+
+ funcs + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_6e.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_6e.html new file mode 100644 index 000000000..7ee4200c2 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_6e.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ noise + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_70.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_70.html new file mode 100644 index 000000000..402fa63cb --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_70.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ plot_flag + energyCalibration +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_73.html b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_73.html new file mode 100644 index 000000000..786cf3968 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/search/variables_73.html @@ -0,0 +1,25 @@ + + + + + + +
+
Loading...
+
+
+ sign + energyCalibrationFunctions +
+
+
Searching...
+
No Matches
+ +
+ + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_b.gif b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_b.gif new file mode 100644 index 000000000..0d623483f Binary files /dev/null and b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_b.gif differ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_l.gif b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_l.gif new file mode 100644 index 000000000..9b1e6337c Binary files /dev/null and b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_l.gif differ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_r.gif b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_r.gif new file mode 100644 index 000000000..ce9dd9f53 Binary files /dev/null and b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tab_r.gif differ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tabs.css b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tabs.css new file mode 100644 index 000000000..a61552a67 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/html/tabs.css @@ -0,0 +1,102 @@ +/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ + +DIV.tabs +{ + float : left; + width : 100%; + background : url("tab_b.gif") repeat-x bottom; + margin-bottom : 4px; +} + +DIV.tabs UL +{ + margin : 0px; + padding-left : 10px; + list-style : none; +} + +DIV.tabs LI, DIV.tabs FORM +{ + display : inline; + margin : 0px; + padding : 0px; +} + +DIV.tabs FORM +{ + float : right; +} + +DIV.tabs A +{ + float : left; + background : url("tab_r.gif") no-repeat right top; + border-bottom : 1px solid #84B0C7; + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + +DIV.tabs A:hover +{ + background-position: 100% -150px; +} + +DIV.tabs A:link, DIV.tabs A:visited, +DIV.tabs A:active, DIV.tabs A:hover +{ + color: #1A419D; +} + +DIV.tabs SPAN +{ + float : left; + display : block; + background : url("tab_l.gif") no-repeat left top; + padding : 5px 9px; + white-space : nowrap; +} + +DIV.tabs INPUT +{ + float : right; + display : inline; + font-size : 1em; +} + +DIV.tabs TD +{ + font-size : x-small; + font-weight : bold; + text-decoration : none; +} + + + +/* Commented Backslash Hack hides rule from IE5-Mac \*/ +DIV.tabs SPAN {float : none;} +/* End IE5-Mac hack */ + +DIV.tabs A:hover SPAN +{ + background-position: 0% -150px; +} + +DIV.tabs LI#current A +{ + background-position: 100% -150px; + border-width : 0px; +} + +DIV.tabs LI#current SPAN +{ + background-position: 0% -150px; + padding-bottom : 6px; +} + +DIV.nav +{ + background : none; + border : none; + border-bottom : 1px solid #84B0C7; +} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/FreeSans.ttf b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/FreeSans.ttf new file mode 100644 index 000000000..b550b90ba Binary files /dev/null and b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/FreeSans.ttf differ diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/Makefile b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/Makefile new file mode 100644 index 000000000..776fcf968 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/Makefile @@ -0,0 +1,39 @@ +all: clean refman.dvi + +ps: refman.ps + +pdf: refman.pdf + +ps_2on1: refman_2on1.ps + +pdf_2on1: refman_2on1.pdf + +refman.ps: refman.dvi + dvips -o refman.ps refman.dvi + +refman.pdf: refman.ps + ps2pdf refman.ps refman.pdf + +refman.dvi: refman.tex doxygen.sty + echo "Running latex..." + latex refman.tex + echo "Running makeindex..." + makeindex refman.idx + echo "Rerunning latex...." + latex refman.tex + latex_count=5 ; \ + while egrep -s 'Rerun (LaTeX|to get cross-references right)' refman.log && [ $$latex_count -gt 0 ] ;\ + do \ + echo "Rerunning latex...." ;\ + latex refman.tex ;\ + latex_count=`expr $$latex_count - 1` ;\ + done + +refman_2on1.ps: refman.ps + psnup -2 refman.ps >refman_2on1.ps + +refman_2on1.pdf: refman_2on1.ps + ps2pdf refman_2on1.ps refman_2on1.pdf + +clean: + rm -f *.ps *.dvi *.aux *.toc *.idx *.ind *.ilg *.log *.out refman.pdf diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/annotated.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/annotated.tex new file mode 100644 index 000000000..dc3097571 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/annotated.tex @@ -0,0 +1,5 @@ +\section{Class List} +Here are the classes, structs, unions and interfaces with brief descriptions:\begin{CompactList} +\item\contentsline{section}{\bf{energy\-Calibration} }{\pageref{classenergyCalibration}}{} +\item\contentsline{section}{\bf{energy\-Calibration\-Functions} (Energy calibration functions )}{\pageref{classenergyCalibrationFunctions}}{} +\end{CompactList} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/classenergyCalibration.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/classenergyCalibration.tex new file mode 100644 index 000000000..ca62e39dd --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/classenergyCalibration.tex @@ -0,0 +1,337 @@ +\section{energy\-Calibration Class Reference} +\label{classenergyCalibration}\index{energyCalibration@{energyCalibration}} +{\tt \#include $<$energy\-Calibration.h$>$} + +\subsection*{Public Member Functions} +\begin{CompactItemize} +\item +\bf{energy\-Calibration} () +\item +\bf{$\sim$energy\-Calibration} () +\item +int \bf{set\-Plot\-Flag} (int p=-1) +\item +int \bf{set\-Scan\-Sign} (int s=0) +\item +int \bf{set\-Charge\-Sharing} (int p=-1) +\item +void \bf{set\-Fit\-Range} (Double\_\-t mi, Double\_\-t ma) +\item +void \bf{get\-Fit\-Range} (Double\_\-t \&mi, Double\_\-t \&ma) +\item +void \bf{set\-Start\-Parameters} (Double\_\-t $\ast$par) +\item +void \bf{get\-Start\-Parameters} (Double\_\-t $\ast$par) +\item +TF1 $\ast$ \bf{fit\-SCurve} (TH1 $\ast$h1, Double\_\-t $\ast$mypar, Double\_\-t $\ast$emypar) +\item +TF1 $\ast$ \bf{fit\-Spectrum} (TH1 $\ast$h1, Double\_\-t $\ast$mypar, Double\_\-t $\ast$emypar) +\item +TGraph\-Errors $\ast$ \bf{linear\-Calibration} (int nscan, Double\_\-t $\ast$en, Double\_\-t $\ast$een, Double\_\-t $\ast$fl, Double\_\-t $\ast$efl, Double\_\-t \&gain, Double\_\-t \&off, Double\_\-t \&egain, Double\_\-t \&eoff) +\item +TGraph\-Errors $\ast$ \bf{calibrate\-Scurves} (int nscan, Double\_\-t $\ast$en, Double\_\-t $\ast$een, TH1F $\ast$$\ast$h1, Double\_\-t \&gain, Double\_\-t \&off, Double\_\-t \&egain, Double\_\-t \&eoff) +\item +TGraph\-Errors $\ast$ \bf{calibrate\-Spectra} (int nscan, Double\_\-t $\ast$en, Double\_\-t $\ast$een, TH1F $\ast$$\ast$h1, Double\_\-t \&gain, Double\_\-t \&off, Double\_\-t \&egain, Double\_\-t \&eoff) +\end{CompactItemize} +\subsection*{Private Member Functions} +\begin{CompactItemize} +\item +TGraph\-Errors $\ast$ \bf{calibrate} (int nscan, Double\_\-t $\ast$en, Double\_\-t $\ast$een, TH1F $\ast$$\ast$h1, Double\_\-t \&gain, Double\_\-t \&off, Double\_\-t \&egain, Double\_\-t \&eoff, int integral=1) +\item +void \bf{init\-Fit\-Function} (TF1 $\ast$fun, TH1 $\ast$h1) +\item +TF1 $\ast$ \bf{fit\-Function} (TF1 $\ast$fun, TH1 $\ast$h1, Double\_\-t $\ast$mypar, Double\_\-t $\ast$emypar) +\end{CompactItemize} +\subsection*{Private Attributes} +\begin{CompactItemize} +\item +int \bf{plot\_\-flag} +\item +int \bf{cs\_\-flag} +\item +Double\_\-t \bf{fit\_\-min} +\item +Double\_\-t \bf{fit\_\-max} +\item +Double\_\-t \bf{bg\_\-offset} +\item +Double\_\-t \bf{bg\_\-slope} +\item +Double\_\-t \bf{flex} +\item +Double\_\-t \bf{noise} +\item +Double\_\-t \bf{ampl} +\item +Double\_\-t \bf{cs\_\-slope} +\item +\bf{energy\-Calibration\-Functions} $\ast$ \bf{funcs} +\item +TF1 $\ast$ \bf{fscurve} +\item +TF1 $\ast$ \bf{fspectrum} +\end{CompactItemize} + + +\subsection{Detailed Description} +class alowing the energy calibration of photon counting and anlogue detectors + + + +\subsection{Constructor \& Destructor Documentation} +\index{energyCalibration@{energy\-Calibration}!energyCalibration@{energyCalibration}} +\index{energyCalibration@{energyCalibration}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}energy\-Calibration::energy\-Calibration ()}\label{classenergyCalibration_16f0658d2b526f52784057b2166efd22} + + +default constructor - creates the function with which the s-curves will be fitted \index{energyCalibration@{energy\-Calibration}!~energyCalibration@{$\sim$energyCalibration}} +\index{~energyCalibration@{$\sim$energyCalibration}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}energy\-Calibration::$\sim$energy\-Calibration ()}\label{classenergyCalibration_3bae2b9c26893daa8f583758509c844f} + + +default destructor - deletes the function with which the s-curves will be fitted + +\subsection{Member Function Documentation} +\index{energyCalibration@{energy\-Calibration}!calibrate@{calibrate}} +\index{calibrate@{calibrate}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TGraph\-Errors$\ast$ energy\-Calibration::calibrate (int {\em nscan}, Double\_\-t $\ast$ {\em en}, Double\_\-t $\ast$ {\em een}, TH1F $\ast$$\ast$ {\em h1}, Double\_\-t \& {\em gain}, Double\_\-t \& {\em off}, Double\_\-t \& {\em egain}, Double\_\-t \& {\em eoff}, int {\em integral} = {\tt 1})\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_378daeddde40b6127ee6ed595506928c} + + +calculates gain and offset for the set of energies \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em nscan}]number of energy scans \item[{\em en}]array of energies (nscan long) \item[{\em een}]array of errors on energies (nscan long) - can be NULL! \item[{\em h1}]array of TH1 \item[{\em gain}]reference to gain resulting from the fit \item[{\em offset}]reference to offset resulting from the fit \item[{\em integral}]1 is an s-curve set (default), 0 spectra \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]graph energy vs peak/inflection point \end{Desc} +\index{energyCalibration@{energy\-Calibration}!calibrateScurves@{calibrateScurves}} +\index{calibrateScurves@{calibrateScurves}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TGraph\-Errors$\ast$ energy\-Calibration::calibrate\-Scurves (int {\em nscan}, Double\_\-t $\ast$ {\em en}, Double\_\-t $\ast$ {\em een}, TH1F $\ast$$\ast$ {\em h1}, Double\_\-t \& {\em gain}, Double\_\-t \& {\em off}, Double\_\-t \& {\em egain}, Double\_\-t \& {\em eoff})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibration_6f5ee6771522a31e4fe1eca143e2aa9b} + + +calculates gain and offset for the set of energy scans \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em nscan}]number of energy scans \item[{\em en}]array of energies (nscan long) \item[{\em een}]array of errors on energies (nscan long) - can be NULL! \item[{\em h1}]array of TH1 \item[{\em gain}]reference to gain resulting from the fit \item[{\em off}]reference to offset resulting from the fit \item[{\em egain}]reference to error on the gain resulting from the fit \item[{\em eoff}]reference to the error on the offset resulting from the fit \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]graph energy vs inflection point \end{Desc} +\index{energyCalibration@{energy\-Calibration}!calibrateSpectra@{calibrateSpectra}} +\index{calibrateSpectra@{calibrateSpectra}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TGraph\-Errors$\ast$ energy\-Calibration::calibrate\-Spectra (int {\em nscan}, Double\_\-t $\ast$ {\em en}, Double\_\-t $\ast$ {\em een}, TH1F $\ast$$\ast$ {\em h1}, Double\_\-t \& {\em gain}, Double\_\-t \& {\em off}, Double\_\-t \& {\em egain}, Double\_\-t \& {\em eoff})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibration_092637f656c0b88d57797e3ebd0f3e58} + + +calculates gain and offset for the set of energy spectra \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em nscan}]number of energy scans \item[{\em en}]array of energies (nscan long) \item[{\em een}]array of errors on energies (nscan long) - can be NULL! \item[{\em h1}]array of TH1 \item[{\em gain}]reference to gain resulting from the fit \item[{\em off}]reference to offset resulting from the fit \item[{\em egain}]reference to error on the gain resulting from the fit \item[{\em eoff}]reference to the error on the offset resulting from the fit \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]graph energy vs peak \end{Desc} +\index{energyCalibration@{energy\-Calibration}!fitFunction@{fitFunction}} +\index{fitFunction@{fitFunction}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TF1$\ast$ energy\-Calibration::fit\-Function (TF1 $\ast$ {\em fun}, TH1 $\ast$ {\em h1}, Double\_\-t $\ast$ {\em mypar}, Double\_\-t $\ast$ {\em emypar})\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_fe1c6dc5f56d12fe06569f401da19729} + + +Perfors the fit according to the flags specified and returns the fitted function \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em fun}]function to fit \item[{\em h1}]histogram to fit \item[{\em mypar}]pointer to fit parameters array \item[{\em emypar}]pointer to fit parameter errors \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]the fitted function - can be used e.g. to get the Chi2 or similar \end{Desc} +\index{energyCalibration@{energy\-Calibration}!fitSCurve@{fitSCurve}} +\index{fitSCurve@{fitSCurve}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TF1$\ast$ energy\-Calibration::fit\-SCurve (TH1 $\ast$ {\em h1}, Double\_\-t $\ast$ {\em mypar}, Double\_\-t $\ast$ {\em emypar})}\label{classenergyCalibration_0dcd8e06e31f7b70488a012db12b2bf8} + + +fits histogram with the s-curve function \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em h1}]1d-histogram to be fitted \item[{\em mypar}]pointer to fit parameters array \item[{\em emypar}]pointer to fit parameter errors \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]the fitted function - can be used e.g. to get the Chi2 or similar \end{Desc} +\index{energyCalibration@{energy\-Calibration}!fitSpectrum@{fitSpectrum}} +\index{fitSpectrum@{fitSpectrum}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TF1$\ast$ energy\-Calibration::fit\-Spectrum (TH1 $\ast$ {\em h1}, Double\_\-t $\ast$ {\em mypar}, Double\_\-t $\ast$ {\em emypar})}\label{classenergyCalibration_7d22b28cd2fad3d334f15f3d6dc7975a} + + +fits histogram with the spectrum \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em h1}]1d-histogram to be fitted \item[{\em mypar}]pointer to fit parameters array \item[{\em emypar}]pointer to fit parameter errors \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]the fitted function - can be used e.g. to get the Chi2 or similar \end{Desc} +\index{energyCalibration@{energy\-Calibration}!getFitRange@{getFitRange}} +\index{getFitRange@{getFitRange}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void energy\-Calibration::get\-Fit\-Range (Double\_\-t \& {\em mi}, Double\_\-t \& {\em ma})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibration_bfb02327a6897bd97525c01697a1ba4f} + + +gets the s-curve fit range \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em mi}]reference for minimum of the fit range (-1 is histogram x-min) \item[{\em ma}]reference for maximum of the fit range (-1 is histogram x-max) \end{description} +\end{Desc} +\index{energyCalibration@{energy\-Calibration}!getStartParameters@{getStartParameters}} +\index{getStartParameters@{getStartParameters}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void energy\-Calibration::get\-Start\-Parameters (Double\_\-t $\ast$ {\em par})}\label{classenergyCalibration_fc7411b7a3191748dfcc90f86b823bf4} + + +get start parameters for the s-curve function \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em par}]parameters, -1 means auto-calculated par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive \end{description} +\end{Desc} +\index{energyCalibration@{energy\-Calibration}!initFitFunction@{initFitFunction}} +\index{initFitFunction@{initFitFunction}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void energy\-Calibration::init\-Fit\-Function (TF1 $\ast$ {\em fun}, TH1 $\ast$ {\em h1})\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_3e84328c11772b6263224340ec924e37} + + +Initializes the start parameters and the range of the fit depending on the histogram characteristics and/or on the start parameters specified by the user \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em fun}]pointer to function to be initialized \item[{\em h1}]histogram from which to extract the range and start parameters, if not already specified by the user \end{description} +\end{Desc} +\index{energyCalibration@{energy\-Calibration}!linearCalibration@{linearCalibration}} +\index{linearCalibration@{linearCalibration}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TGraph\-Errors$\ast$ energy\-Calibration::linear\-Calibration (int {\em nscan}, Double\_\-t $\ast$ {\em en}, Double\_\-t $\ast$ {\em een}, Double\_\-t $\ast$ {\em fl}, Double\_\-t $\ast$ {\em efl}, Double\_\-t \& {\em gain}, Double\_\-t \& {\em off}, Double\_\-t \& {\em egain}, Double\_\-t \& {\em eoff})}\label{classenergyCalibration_c7f46f2d051f28211681e851f99d3fc4} + + +calculates gain and offset for the set of inflection points \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em nscan}]number of energy scans \item[{\em en}]array of energies (nscan long) \item[{\em een}]array of errors on energies (nscan long) - can be NULL! \item[{\em fl}]array of inflection points (nscan long) \item[{\em efl}]array of errors on the inflection points (nscan long) \item[{\em gain}]reference to gain resulting from the fit \item[{\em off}]reference to offset resulting from the fit \item[{\em egain}]reference to error on the gain resulting from the fit \item[{\em eoff}]reference to the error on the offset resulting from the fit \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]graph energy vs inflection point \end{Desc} +\index{energyCalibration@{energy\-Calibration}!setChargeSharing@{setChargeSharing}} +\index{setChargeSharing@{setChargeSharing}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int energy\-Calibration::set\-Charge\-Sharing (int {\em p} = {\tt -1})}\label{classenergyCalibration_e2809b419799e8b199944f185d4ebab8} + + +sets plot flag \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em p}]plot flag (-1 gets, 0 unsets, $>$0 plot) \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]current plot flag \end{Desc} +\index{energyCalibration@{energy\-Calibration}!setFitRange@{setFitRange}} +\index{setFitRange@{setFitRange}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void energy\-Calibration::set\-Fit\-Range (Double\_\-t {\em mi}, Double\_\-t {\em ma})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibration_695cef5428a833d515172d987774f67b} + + +sets the s-curve fit range \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em mi}]minimum of the fit range (-1 is histogram x-min) \item[{\em ma}]maximum of the fit range (-1 is histogram x-max) \end{description} +\end{Desc} +\index{energyCalibration@{energy\-Calibration}!setPlotFlag@{setPlotFlag}} +\index{setPlotFlag@{setPlotFlag}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int energy\-Calibration::set\-Plot\-Flag (int {\em p} = {\tt -1})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibration_3d9af0857f7a68b7e4519917ea97e6be} + + +sets plot flag \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em p}]plot flag (-1 gets, 0 unsets, $>$0 plot) \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]current plot flag \end{Desc} +\index{energyCalibration@{energy\-Calibration}!setScanSign@{setScanSign}} +\index{setScanSign@{setScanSign}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int energy\-Calibration::set\-Scan\-Sign (int {\em s} = {\tt 0})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibration_7dbf1676b30ffe90c5aa917f1b2b77ee} + + +sets scan sign \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em s}]can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) \end{Desc} +\index{energyCalibration@{energy\-Calibration}!setStartParameters@{setStartParameters}} +\index{setStartParameters@{setStartParameters}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}void energy\-Calibration::set\-Start\-Parameters (Double\_\-t $\ast$ {\em par})}\label{classenergyCalibration_ba156f5290f7b404d7b8ea735fd7e7bf} + + +set start parameters for the s-curve function \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em par}]parameters, -1 sets to auto-calculation par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive \end{description} +\end{Desc} + + +\subsection{Member Data Documentation} +\index{energyCalibration@{energy\-Calibration}!ampl@{ampl}} +\index{ampl@{ampl}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::ampl}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_77b954cd513271d2cfafee6033435584} + + +start value for the number of photons \index{energyCalibration@{energy\-Calibration}!bg_offset@{bg\_\-offset}} +\index{bg_offset@{bg\_\-offset}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::bg\_\-offset}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_aa11f256a8b0a94c28a98d068013b327} + + +start value for the background pedestal \index{energyCalibration@{energy\-Calibration}!bg_slope@{bg\_\-slope}} +\index{bg_slope@{bg\_\-slope}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::bg\_\-slope}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_9676e5cc2757c723c2262d641fb4b8b4} + + +start value for the background slope \index{energyCalibration@{energy\-Calibration}!cs_flag@{cs\_\-flag}} +\index{cs_flag@{cs\_\-flag}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int \bf{energy\-Calibration::cs\_\-flag}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_ce0be11dcc8418db3c7c2b139a015c96} + + +0 functions without charge sharing contribution, $>$0 with charge sharing contribution \index{energyCalibration@{energy\-Calibration}!cs_slope@{cs\_\-slope}} +\index{cs_slope@{cs\_\-slope}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::cs\_\-slope}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_ca1efedbfea0ad5c9ea2d794e3fb368d} + + +start value for the charge sharing slope \index{energyCalibration@{energy\-Calibration}!fit_max@{fit\_\-max}} +\index{fit_max@{fit\_\-max}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::fit\_\-max}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_e979386a3f787ef706f4a9ec5bf41d7d} + + +maximum of the s-curve fitting range, -1 is histogram x-max \index{energyCalibration@{energy\-Calibration}!fit_min@{fit\_\-min}} +\index{fit_min@{fit\_\-min}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::fit\_\-min}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_262f574732186cdd8d3a11344d03d0bb} + + +minimum of the s-curve fitting range, -1 is histogram x-min \index{energyCalibration@{energy\-Calibration}!flex@{flex}} +\index{flex@{flex}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::flex}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_b99d770f1c9af68d591ed20847813ad1} + + +start value for the inflection point \index{energyCalibration@{energy\-Calibration}!fscurve@{fscurve}} +\index{fscurve@{fscurve}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TF1$\ast$ \bf{energy\-Calibration::fscurve}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_57706a328324c25dd9f8ba6d1486e4ce} + + +function with which the s-curve will be fitted \index{energyCalibration@{energy\-Calibration}!fspectrum@{fspectrum}} +\index{fspectrum@{fspectrum}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}TF1$\ast$ \bf{energy\-Calibration::fspectrum}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_2ee734ab28b78dc5786a7ba430f8baa5} + + +function with which the spectrum will be fitted \index{energyCalibration@{energy\-Calibration}!funcs@{funcs}} +\index{funcs@{funcs}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}\bf{energy\-Calibration\-Functions}$\ast$ \bf{energy\-Calibration::funcs}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_e9b3307bf858331241871bde42fdd24e} + + +\index{energyCalibration@{energy\-Calibration}!noise@{noise}} +\index{noise@{noise}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t \bf{energy\-Calibration::noise}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_4461206397e2442c92be9151ee231ec5} + + +start value for the noise \index{energyCalibration@{energy\-Calibration}!plot_flag@{plot\_\-flag}} +\index{plot_flag@{plot\_\-flag}!energyCalibration@{energy\-Calibration}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int \bf{energy\-Calibration::plot\_\-flag}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibration_4edfb157df3624be677177dec0f9555b} + + +0 does not plot, $>$0 plots (flags?) + +The documentation for this class was generated from the following file:\begin{CompactItemize} +\item +\bf{energy\-Calibration.h}\end{CompactItemize} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/classenergyCalibrationFunctions.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/classenergyCalibrationFunctions.tex new file mode 100644 index 000000000..1e8920959 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/classenergyCalibrationFunctions.tex @@ -0,0 +1,135 @@ +\section{energy\-Calibration\-Functions Class Reference} +\label{classenergyCalibrationFunctions}\index{energyCalibrationFunctions@{energyCalibrationFunctions}} +Energy calibration functions. + + +{\tt \#include $<$energy\-Calibration.h$>$} + +\subsection*{Public Member Functions} +\begin{CompactItemize} +\item +\bf{energy\-Calibration\-Functions} (int s=-1) +\item +int \bf{set\-Scan\-Sign} (int s=0) +\item +Double\_\-t \bf{gauss\-Charge\-Sharing} (Double\_\-t $\ast$x, Double\_\-t $\ast$par) +\item +Double\_\-t \bf{erf\-Function} (Double\_\-t $\ast$x, Double\_\-t $\ast$par) +\item +Double\_\-t \bf{erf\-Function\-Charge\-Sharing} (Double\_\-t $\ast$x, Double\_\-t $\ast$par) +\item +Double\_\-t \bf{erf\-Func\-Fluo} (Double\_\-t $\ast$x, Double\_\-t $\ast$par) +\item +Double\_\-t \bf{spectrum} (Double\_\-t $\ast$x, Double\_\-t $\ast$par) +\item +Double\_\-t \bf{scurve} (Double\_\-t $\ast$x, Double\_\-t $\ast$par) +\item +Double\_\-t \bf{scurve\-Fluo} (Double\_\-t $\ast$x, Double\_\-t $\ast$par) +\end{CompactItemize} +\subsection*{Static Public Member Functions} +\begin{CompactItemize} +\item +static float \bf{median} (float $\ast$x, int n) +\item +static int \bf{quick\_\-select} (int arr[$\,$], int n) +\item +static int \bf{kth\_\-smallest} (int $\ast$a, int n, int k) +\end{CompactItemize} +\subsection*{Private Attributes} +\begin{CompactItemize} +\item +int \bf{sign} +\end{CompactItemize} + + +\subsection{Detailed Description} +Energy calibration functions. + +class containing all the possible energy calibration functions (scurves with and without charge sharing, gaussian spectrum with and without charge sharing, possibility of chosing the sign of the X-axis) + + + +\subsection{Constructor \& Destructor Documentation} +\index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!energyCalibrationFunctions@{energyCalibrationFunctions}} +\index{energyCalibrationFunctions@{energyCalibrationFunctions}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}energy\-Calibration\-Functions::energy\-Calibration\-Functions (int {\em s} = {\tt -1})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibrationFunctions_8c17162b89f3b2e642004e7c88a22ac2} + + + + +\subsection{Member Function Documentation} +\index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!erfFuncFluo@{erfFuncFluo}} +\index{erfFuncFluo@{erfFuncFluo}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t energy\-Calibration\-Functions::erf\-Func\-Fluo (Double\_\-t $\ast$ {\em x}, Double\_\-t $\ast$ {\em par})}\label{classenergyCalibrationFunctions_a5fbe9da48bc2ef90b699e06ea8c5111} + + +Double Erf function with charge sharing slope par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point of the first energy par[3] is the RMS of the first energy par[4] is the amplitude of the first energy par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) par[6] is the inflection point of the second energy par[7] is the RMS of the second energy par[8] is the amplitude of the second energy par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!erfFunction@{erfFunction}} +\index{erfFunction@{erfFunction}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t energy\-Calibration\-Functions::erf\-Function (Double\_\-t $\ast$ {\em x}, Double\_\-t $\ast$ {\em par})}\label{classenergyCalibrationFunctions_2da1e3b9a10d23233256f8c2234f2457} + + +Basic erf function par[0] is the inflection point par[1] is the RMS par[2] is the amplitude \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!erfFunctionChargeSharing@{erfFunctionChargeSharing}} +\index{erfFunctionChargeSharing@{erfFunctionChargeSharing}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t energy\-Calibration\-Functions::erf\-Function\-Charge\-Sharing (Double\_\-t $\ast$ {\em x}, Double\_\-t $\ast$ {\em par})}\label{classenergyCalibrationFunctions_8d1b3d0f8b30423dad56d8ce5323a4a8} + + +Erf function with charge sharing slope par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!gaussChargeSharing@{gaussChargeSharing}} +\index{gaussChargeSharing@{gaussChargeSharing}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t energy\-Calibration\-Functions::gauss\-Charge\-Sharing (Double\_\-t $\ast$ {\em x}, Double\_\-t $\ast$ {\em par})}\label{classenergyCalibrationFunctions_e9582e5c46d27ad25d6139d0386698f7} + + +Gaussian Function with charge sharing pedestal par[0] is the absolute height of the background pedestal par[1] is the slope of the background pedestal par[2] is the gaussian peak position par[3] is the RMS of the gaussian (and of the pedestal) par[4] is the height of the function par[5] is the fractional height of the charge sharing pedestal (scales with par[3]) \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!kth_smallest@{kth\_\-smallest}} +\index{kth_smallest@{kth\_\-smallest}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}static int energy\-Calibration\-Functions::kth\_\-smallest (int $\ast$ {\em a}, int {\em n}, int {\em k})\hspace{0.3cm}{\tt [static]}}\label{classenergyCalibrationFunctions_7d9a7b8d0c8ff69638a5fbb9f4c04b90} + + +Calculates the median of an array of n elements (swaps the arrays!) \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!median@{median}} +\index{median@{median}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}static float energy\-Calibration\-Functions::median (float $\ast$ {\em x}, int {\em n})\hspace{0.3cm}{\tt [static]}}\label{classenergyCalibrationFunctions_37f557bacb75213073c8d421cc1240f4} + + +Calculates the median of an array of n elements \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!quick_select@{quick\_\-select}} +\index{quick_select@{quick\_\-select}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}static int energy\-Calibration\-Functions::quick\_\-select (int {\em arr}[$\,$], int {\em n})\hspace{0.3cm}{\tt [static]}}\label{classenergyCalibrationFunctions_a3ab0e7c3c862fb51dfda78f1b09a55c} + + +Calculates the median of an array of n elements (swaps the arrays!) \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!scurve@{scurve}} +\index{scurve@{scurve}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t energy\-Calibration\-Functions::scurve (Double\_\-t $\ast$ {\em x}, Double\_\-t $\ast$ {\em par})}\label{classenergyCalibrationFunctions_e220482622e88a46b12498b0e4d8113a} + + +Erf function with charge sharing slope with the correct scan sign par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point par[3] is the RMS par[4] is the amplitude par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!scurveFluo@{scurveFluo}} +\index{scurveFluo@{scurveFluo}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t energy\-Calibration\-Functions::scurve\-Fluo (Double\_\-t $\ast$ {\em x}, Double\_\-t $\ast$ {\em par})}\label{classenergyCalibrationFunctions_4eba39623b518d67a63192970a78f530} + + +Double Erf function with charge sharing slope par[0] is the pedestal par[1] is the slope of the pedestal par[2] is the inflection point of the first energy par[3] is the RMS of the first energy par[4] is the amplitude of the first energy par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) par[6] is the inflection point of the second energy par[7] is the RMS of the second energy par[8] is the amplitude of the second energy par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) \index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!setScanSign@{setScanSign}} +\index{setScanSign@{setScanSign}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int energy\-Calibration\-Functions::set\-Scan\-Sign (int {\em s} = {\tt 0})\hspace{0.3cm}{\tt [inline]}}\label{classenergyCalibrationFunctions_716759a1ae09ea3c841f824af3ece415} + + +sets scan sign \begin{Desc} +\item[Parameters:] +\begin{description} +\item[{\em s}]can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets \end{description} +\end{Desc} +\begin{Desc} +\item[Returns:]current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) \end{Desc} +\index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!spectrum@{spectrum}} +\index{spectrum@{spectrum}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}Double\_\-t energy\-Calibration\-Functions::spectrum (Double\_\-t $\ast$ {\em x}, Double\_\-t $\ast$ {\em par})}\label{classenergyCalibrationFunctions_015eb05dc34b77642ab2a2a9f126f170} + + +static function Gaussian with charge sharing pedestal with the correct scan sign par[0] is the absolute height of the background pedestal par[1] is the fractional height of the charge sharing pedestal (scales with par[3] par[2] is the gaussian peak position par[3] is the RMS of the gaussian (and of the pedestal) par[4] is the height of the function + +\subsection{Member Data Documentation} +\index{energyCalibrationFunctions@{energy\-Calibration\-Functions}!sign@{sign}} +\index{sign@{sign}!energyCalibrationFunctions@{energy\-Calibration\-Functions}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}int \bf{energy\-Calibration\-Functions::sign}\hspace{0.3cm}{\tt [private]}}\label{classenergyCalibrationFunctions_4fc7c435169b5bf4672cf654270097d0} + + + + +The documentation for this class was generated from the following file:\begin{CompactItemize} +\item +\bf{energy\-Calibration.h}\end{CompactItemize} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/doxygen.sty b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/doxygen.sty new file mode 100644 index 000000000..ff2b57e23 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/doxygen.sty @@ -0,0 +1,78 @@ +\NeedsTeXFormat{LaTeX2e} +\ProvidesPackage{doxygen} +\RequirePackage{calc} +\RequirePackage{array} +\pagestyle{fancyplain} +\newcommand{\clearemptydoublepage}{\newpage{\pagestyle{empty}\cleardoublepage}} +\renewcommand{\chaptermark}[1]{\markboth{#1}{}} +\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} +\lhead[\fancyplain{}{\bfseries\thepage}] + {\fancyplain{}{\bfseries\rightmark}} +\rhead[\fancyplain{}{\bfseries\leftmark}] + {\fancyplain{}{\bfseries\thepage}} +\rfoot[\fancyplain{}{\bfseries\scriptsize Generated on Tue Mar 27 16:32:29 2012 by Doxygen }]{} +\lfoot[]{\fancyplain{}{\bfseries\scriptsize Generated on Tue Mar 27 16:32:29 2012 by Doxygen }} +\cfoot{} +\newenvironment{Code} +{\footnotesize} +{\normalsize} +\newcommand{\doxyref}[3]{\textbf{#1} (\textnormal{#2}\,\pageref{#3})} +\newenvironment{DocInclude} +{\footnotesize} +{\normalsize} +\newenvironment{VerbInclude} +{\footnotesize} +{\normalsize} +\newenvironment{Image} +{\begin{figure}[H]} +{\end{figure}} +\newenvironment{ImageNoCaption}{}{} +\newenvironment{CompactList} +{\begin{list}{}{ + \setlength{\leftmargin}{0.5cm} + \setlength{\itemsep}{0pt} + \setlength{\parsep}{0pt} + \setlength{\topsep}{0pt} + \renewcommand{\makelabel}{\hfill}}} +{\end{list}} +\newenvironment{CompactItemize} +{ + \begin{itemize} + \setlength{\itemsep}{-3pt} + \setlength{\parsep}{0pt} + \setlength{\topsep}{0pt} + \setlength{\partopsep}{0pt} +} +{\end{itemize}} +\newcommand{\PBS}[1]{\let\temp=\\#1\let\\=\temp} +\newlength{\tmplength} +\newenvironment{TabularC}[1] +{ +\setlength{\tmplength} + {\linewidth/(#1)-\tabcolsep*2-\arrayrulewidth*(#1+1)/(#1)} + \par\begin{tabular*}{\linewidth} + {*{#1}{|>{\PBS\raggedright\hspace{0pt}}p{\the\tmplength}}|} +} +{\end{tabular*}\par} +\newcommand{\entrylabel}[1]{ + {\parbox[b]{\labelwidth-4pt}{\makebox[0pt][l]{\textbf{#1}}\vspace{1.5\baselineskip}}}} +\newenvironment{Desc} +{\begin{list}{} + { + \settowidth{\labelwidth}{40pt} + \setlength{\leftmargin}{\labelwidth} + \setlength{\parsep}{0pt} + \setlength{\itemsep}{-4pt} + \renewcommand{\makelabel}{\entrylabel} + } +} +{\end{list}} +\newenvironment{Indent} + {\begin{list}{}{\setlength{\leftmargin}{0.5cm}} + \item[]\ignorespaces} + {\unskip\end{list}} +\setlength{\parindent}{0cm} +\setlength{\parskip}{0.2cm} +\addtocounter{secnumdepth}{1} +\sloppy +\usepackage[T1]{fontenc} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/energyCalibration_8h.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/energyCalibration_8h.tex new file mode 100644 index 000000000..3c9d9f6c8 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/energyCalibration_8h.tex @@ -0,0 +1,37 @@ +\section{energy\-Calibration.h File Reference} +\label{energyCalibration_8h}\index{energyCalibration.h@{energyCalibration.h}} +{\tt \#include $<$TROOT.h$>$}\par +{\tt \#include $<$TF1.h$>$}\par +\subsection*{Namespaces} +\begin{CompactItemize} +\item +namespace \bf{std} +\end{CompactItemize} +\subsection*{Classes} +\begin{CompactItemize} +\item +class \bf{energy\-Calibration\-Functions} +\begin{CompactList}\small\item\em Energy calibration functions. \item\end{CompactList}\item +class \bf{energy\-Calibration} +\end{CompactItemize} +\subsection*{Variables} +\begin{CompactItemize} +\item +const float \bf{conven} = 1000./3.6 +\item +const float \bf{el} = 1.67E-4 +\end{CompactItemize} + + +\subsection{Variable Documentation} +\index{energyCalibration.h@{energy\-Calibration.h}!conven@{conven}} +\index{conven@{conven}!energyCalibration.h@{energy\-Calibration.h}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}const float \bf{conven} = 1000./3.6}\label{energyCalibration_8h_a48a6c1eb7d418c5d0618fbb161ae321} + + +electrons/ke\-V \index{energyCalibration.h@{energy\-Calibration.h}!el@{el}} +\index{el@{el}!energyCalibration.h@{energy\-Calibration.h}} +\subsubsection{\setlength{\rightskip}{0pt plus 5cm}const float \bf{el} = 1.67E-4}\label{energyCalibration_8h_d1db7b454cab6ae1749310d7f444849b} + + +electron charge in f\-C \ No newline at end of file diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/files.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/files.tex new file mode 100644 index 000000000..d3d460d1e --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/files.tex @@ -0,0 +1,4 @@ +\section{File List} +Here is a list of all files with brief descriptions:\begin{CompactList} +\item\contentsline{section}{\bf{energy\-Calibration.h} }{\pageref{energyCalibration_8h}}{} +\end{CompactList} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/index.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/index.tex new file mode 100644 index 000000000..4b31a1dff --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/index.tex @@ -0,0 +1,3 @@ +\section{Introduction}\label{index_intro_sec} +We know very well s-curves etc. but at the end everybody uses different functions ;-).\subsection{Motivation}\label{index_mot_sec} +It would be greate to use everybody the same functions... \ No newline at end of file diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/namespaces.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/namespaces.tex new file mode 100644 index 000000000..c2ca33382 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/namespaces.tex @@ -0,0 +1,4 @@ +\section{Namespace List} +Here is a list of all namespaces with brief descriptions:\begin{CompactList} +\item\contentsline{section}{\bf{std} }{\pageref{namespacestd}}{} +\end{CompactList} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/namespacestd.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/namespacestd.tex new file mode 100644 index 000000000..a1732dd75 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/namespacestd.tex @@ -0,0 +1,4 @@ +\section{std Namespace Reference} +\label{namespacestd}\index{std@{std}} + + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/refman.tex b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/refman.tex new file mode 100644 index 000000000..110991b6b --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/docs/latex/refman.tex @@ -0,0 +1,46 @@ +\documentclass[a4paper]{book} +\usepackage{a4wide} +\usepackage{makeidx} +\usepackage{fancyhdr} +\usepackage{graphicx} +\usepackage{multicol} +\usepackage{float} +\usepackage{textcomp} +\usepackage{alltt} +\usepackage{doxygen} +\makeindex +\setcounter{tocdepth}{1} +\renewcommand{\footrulewidth}{0.4pt} +\begin{document} +\begin{titlepage} +\vspace*{7cm} +\begin{center} +{\Large Reference Manual}\\ +\vspace*{1cm} +{\large Generated by Doxygen 1.4.7}\\ +\vspace*{0.5cm} +{\small Tue Mar 27 16:32:29 2012}\\ +\end{center} +\end{titlepage} +\clearemptydoublepage +\pagenumbering{roman} +\tableofcontents +\clearemptydoublepage +\pagenumbering{arabic} +\chapter{Common Root library for SLS detectors data analysis } +\label{index}\input{index} +\chapter{Namespace Index} +\input{namespaces} +\chapter{Class Index} +\input{annotated} +\chapter{File Index} +\input{files} +\chapter{Namespace Documentation} +\input{namespacestd} +\chapter{Class Documentation} +\input{classenergyCalibration} +\include{classenergyCalibrationFunctions} +\chapter{File Documentation} +\input{energyCalibration_8h} +\printindex +\end{document} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/doxy.config b/slsDetectorSoftware/slsDetectorAnalysis/doxy.config new file mode 100644 index 000000000..c6f5f7f13 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/doxy.config @@ -0,0 +1,65 @@ +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +INPUT = energyCalibration.h + + +OUTPUT_DIRECTORY = docs + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/enCalLogClass.h b/slsDetectorSoftware/slsDetectorAnalysis/enCalLogClass.h new file mode 100644 index 000000000..054263687 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/enCalLogClass.h @@ -0,0 +1,133 @@ +#ifndef ENCALLOGCLASS_H +#define ENCALLOGCLASS_H + +#include +#include + + +#ifdef __CINT__ +#define MYROOT +#endif + +#ifndef MYROOT +#include "slsDetectorCommand.h" +#include "slsDetectorUtils.h" +#include "sls_detector_defs.h" +#endif + +using namespace std; + +class enCalLogClass { + + + public: + +#ifndef MYROOT + enCalLogClass(slsDetectorUtils *det){ \ + char cmd[1000]; \ + char *argv[2]; \ + strcpy(vars[0],"settings"); \ + strcpy(vars[1],"type"); \ + strcpy(vars[2],"nmod"); \ + strcpy(vars[3],"modulenumber"); \ + argv[0]=cmd; \ + sprintf(cmd,"_%d.encal",det->getFileIndex()); \ + outfile.open(string(det->getFilePath()+string("/")+det->getFileName()+string(cmd)).c_str()); \ + myDet=new slsDetectorCommand(det); \ + strcpy(cmd,vars[0]); \ + outfile << cmd << " " << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ + strcpy(cmd,vars[1]); \ + outfile << cmd << " " << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ + strcpy(cmd,vars[2]); \ + outfile << cmd << " " << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ + for (int im=0; imsetNumberOfModules(); im++) { \ + sprintf(cmd,"%s:%d",vars[3],im); \ + outfile << cmd << " " << myDet->executeLine(1,argv,slsDetectorDefs::GET_ACTION) << endl; \ + } \ + }; + + ~enCalLogClass(){delete myDet; outfile.close();}; +#else + enCalLogClass() { \ + strcpy(vars[0],"settings"); \ + strcpy(vars[1],"type"); \ + strcpy(vars[2],"nmod"); \ + strcpy(vars[3],"modulenumber"); \ + }; + ~enCalLogClass(){}; +#endif + + + int addStep(double threshold, string fname) {outfile << threshold << " " << fname << endl; return 0;}; + + + // + + int readHeader(ifstream &infile, char *settings, int &nmod, int &chanspermod, int *mods ) { \ + nmod=0; strcpy(settings,"unknown"); chanspermod=0; \ + char line[1000],myarg[100]; \ + int dum; \ + for (int iv=0; iv<3; iv++) { \ + infile.getline(line,1000); \ + switch (iv) { \ + case 0: \ + sscanf(line,"settings %s", settings); \ + break; \ + case 1: \ + sscanf(line,"type %s", myarg); \ + if (string(myarg).find("Mythen")!=string::npos) \ + chanspermod=1280; \ + else if (string(myarg).find("Gotthard")!=string::npos) \ + chanspermod=1280; \ + else \ + chanspermod=65535; \ + break; \ + case 2: \ + sscanf(line,"nmod %d", &nmod); \ + break; \ + default: \ + ; \ + }; \ + if (infile.bad() || infile.eof()) { cout << "bad file "<< iv << endl; return -1;} \ + } \ + for (int im=0; im +#include +#include +#include +#endif + +#include + +#define max(a,b) ((a) > (b) ? (a) : (b)) +#define min(a,b) ((a) < (b) ? (a) : (b)) +#define ELEM_SWAP(a,b) { register int t=(a);(a)=(b);(b)=t; } + + +using namespace std; + +#ifdef MYROOT +Double_t energyCalibrationFunctions::gaussChargeSharing(Double_t *x, Double_t *par) { + Double_t f, arg=0; + if (par[3]!=0) arg=(x[0]-par[2])/par[3]; + f=par[4]*TMath::Exp(-1*arg*arg/2.); + f=f+par[5]*(par[4]/2*(TMath::Erfc(sign*arg/(TMath::Sqrt(2.)))))+par[0]-par[1]*sign*x[0]; + return f; +} + +// basic erf function +Double_t energyCalibrationFunctions::erfFunction(Double_t *x, Double_t *par) { + double arg=0; + if (par[1]!=0) arg=(par[0]-x[0])/par[1]; + return ((par[2]/2.*(1+TMath::Erf(sign*arg/(TMath::Sqrt(2)))))); +}; + + +Double_t energyCalibrationFunctions::erfFunctionChargeSharing(Double_t *x, Double_t *par) { + Double_t f; + + f=erfFunction(x, par+2)*(1+par[5]*(par[2]-x[0]))+par[0]-par[1]*x[0]*sign; + return f; +}; + + +Double_t energyCalibrationFunctions::erfFuncFluo(Double_t *x, Double_t *par) { + Double_t f; + f=erfFunctionChargeSharing(x, par)+erfFunction(x, par+6)*(1+par[9]*(par[6]-x[0])); + return f; +}; +#endif + +double energyCalibrationFunctions::median(double *x, int n){ + // sorts x into xmed array and returns median + // n is number of values already in the xmed array + double xmed[n]; + int k,i,j; + + for (i=0; i*(x+j)) + k++; + if (*(x+i)==*(x+j)) { + if (i>j) + k++; + } + } + xmed[k]=*(x+i); + } + k=n/2; + return xmed[k]; +} + + +int energyCalibrationFunctions::quick_select(int arr[], int n){ + int low, high ; + int median; + int middle, ll, hh; + + low = 0 ; high = n-1 ; median = (low + high) / 2; + for (;;) { + if (high <= low) /* One element only */ + return arr[median] ; + + if (high == low + 1) { /* Two elements only */ + if (arr[low] > arr[high]) + ELEM_SWAP(arr[low], arr[high]) ; + return arr[median] ; + } + + /* Find median of low, middle and high items; swap into position low */ + middle = (low + high) / 2; + if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; + if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; + if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; + + /* Swap low item (now in position middle) into position (low+1) */ + ELEM_SWAP(arr[middle], arr[low+1]) ; + + /* Nibble from each end towards middle, swapping items when stuck */ + ll = low + 1; + hh = high; + for (;;) { + do ll++; while (arr[low] > arr[ll]) ; + do hh--; while (arr[hh] > arr[low]) ; + + if (hh < ll) + break; + + ELEM_SWAP(arr[ll], arr[hh]) ; + } + + /* Swap middle item (in position low) back into correct position */ + ELEM_SWAP(arr[low], arr[hh]) ; + + /* Re-set active partition */ + if (hh <= median) + low = ll; + if (hh >= median) + high = hh - 1; + } +} + +int energyCalibrationFunctions::kth_smallest(int *a, int n, int k){ + register int i,j,l,m ; + register double x ; + + l=0 ; m=n-1 ; + while (lSetParNames("Background Offset","Background Slope","Inflection Point","Noise RMS", "Number of Photons","Charge Sharing Slope"); + + fspectrum=new TF1("fspectrum",funcs,&energyCalibrationFunctions::spectrum,0,1000,6,"energyCalibrationFunctions","spectrum"); + fspectrum->SetParNames("Background Pedestal","Background slope", "Peak position","Noise RMS", "Number of Photons","Charge Sharing Pedestal"); + +#endif + + +} + + + +void energyCalibration::fixParameter(int ip, Double_t val){ + + fscurve->FixParameter(ip, val); + fspectrum->FixParameter(ip, val); +} + + +void energyCalibration::releaseParameter(int ip){ + + fscurve->ReleaseParameter(ip); + fspectrum->ReleaseParameter(ip); +} + + + + + + + +energyCalibration::~energyCalibration(){ +#ifdef MYROOT + delete fscurve; + delete fspectrum; +#endif + +} + +#ifdef MYROOT + + + +TH1F* energyCalibration::createMedianHistogram(TH2F* h2, int ch0, int nch) { + + if (h2==NULL || nch==0) + return NULL; + + double *x=new double[nch]; + TH1F *h1=NULL; + + double val=-1; + double me=0; + + + h1=new TH1F("median","Median",h2->GetYaxis()->GetNbins(),h2->GetYaxis()->GetXmin(),h2->GetYaxis()->GetXmax()); + + + for (int ib=0; ibGetXaxis()->GetNbins(); ib++) { + me=0; + for (int ich=0; ichGetBinContent(ch0+ich+1,ib+1); + me+=x[ich]; + } + cout << ib << " calculating median ch0=" << ch0 << " nch=" << nch << endl; + val=energyCalibrationFunctions::median(x, nch); + cout << "median=" << val << " mean= " << me/nch << endl; + h1->SetBinContent(ib+1,val); + } + delete [] x; + return h1; + + + +} + + + + + + + + + + + + + + +void energyCalibration::setStartParameters(Double_t *par){ + bg_offset=par[0]; + bg_slope=par[1]; + flex=par[2]; + noise=par[3]; + ampl=par[4]; + cs_slope=par[5]; +} + + +void energyCalibration::getStartParameters(Double_t *par){ + par[0]=bg_offset; + par[1]=bg_slope; + par[2]=flex; + par[3]=noise; + par[4]=ampl; + par[5]=cs_slope; +} + +#endif +int energyCalibration::setChargeSharing(int p) { + if (p>=0) { + cs_flag=p; +#ifdef MYROOT + if (p) { + fscurve->ReleaseParameter(5); + fspectrum->ReleaseParameter(1); + } else { + fscurve->FixParameter(5,0); + fspectrum->FixParameter(1,0); + } +#endif + } + + return cs_flag; +} + + +#ifdef MYROOT +void energyCalibration::initFitFunction(TF1 *fun, TH1 *h1) { + + Double_t min=fit_min, max=fit_max; + + Double_t mypar[6]; + + if (max==-1) + max=h1->GetXaxis()->GetXmax(); + + if (min==-1) + min=h1->GetXaxis()->GetXmin(); + + + if (bg_offset==-1) + mypar[0]=0; + else + mypar[0]=bg_offset; + + + if (bg_slope==-1) + mypar[1]=0; + else + mypar[1]=bg_slope; + + + if (flex==-1) + mypar[2]=(min+max)/2.; + else + mypar[2]=flex; + + + if (noise==-1) + mypar[3]=0.1; + else + mypar[3]=noise; + + if (ampl==-1) + mypar[4]=h1->GetBinContent(h1->GetXaxis()->FindBin(0.5*(max+min))); + else + mypar[4]=ampl; + + if (cs_slope==-1) + mypar[5]=0; + else + mypar[5]=cs_slope; + + fun->SetParameters(mypar); + + fun->SetRange(min,max); + +} + + +TF1* energyCalibration::fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar) { + + + TF1* fitfun; + + char fname[100]; + + strcpy(fname, fun->GetName()); + + if (plot_flag) { + h1->Fit(fname,"R"); + } else + h1->Fit(fname,"R0Q"); + + + fitfun= h1->GetFunction(fname); + fitfun->GetParameters(mypar); + for (int ip=0; ip<6; ip++) { + emypar[ip]=fitfun->GetParError(ip); + } + return fitfun; +} + +TF1* energyCalibration::fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar) { + initFitFunction(fscurve,h1); + return fitFunction(fscurve, h1, mypar, emypar); +} + + + + + +TF1* energyCalibration::fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar) { + initFitFunction(fspectrum,h1); + return fitFunction(fspectrum, h1, mypar, emypar); +} + + + +TGraphErrors* energyCalibration::linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff) { + + TGraphErrors *gr; + + Double_t mypar[2]; + + gr = new TGraphErrors(nscan,en,fl,een,efl); + + if (plot_flag) { + gr->Fit("pol1"); + gr->SetMarkerStyle(20); + } else + gr->Fit("pol1","0Q"); + + TF1 *fitfun= gr->GetFunction("pol1"); + fitfun->GetParameters(mypar); + + egain=fitfun->GetParError(1); + eoff=fitfun->GetParError(0); + + gain=funcs->setScanSign()*mypar[1]; + off=mypar[0]; + + return gr; +} + + +TGraphErrors* energyCalibration::calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral) { + + TH1F *h; + + Double_t mypar[6], emypar[6]; + Double_t fl[nscan], efl[nscan]; + + + for (int ien=0; ien +#include +class TH1F; +class TH2F; +class TGraphErrors; +#endif + + +using namespace std; + + + + +const double conven=1000./3.6; /**< electrons/keV */ +const double el=1.67E-4; /**< electron charge in fC */ + + + +/** + \mainpage Common Root library for SLS detectors data analysis + * + * \section intro_sec Introduction + We know very well s-curves etc. but at the end everybody uses different functions ;-). + + * \subsection mot_sec Motivation + It would be greate to use everybody the same functions... + +*/ + + +/** + * + * +@libdoc The energiCalibration class contains all the necessary functions for s-curve fitting and linear calibration of the threshold. + * + * @short Energy calibration functions + * @author Anna Bergamaschi + * @version 0.1alpha + + + */ + +/** + class containing all the possible energy calibration functions (scurves with and without charge sharing, gaussian spectrum with and without charge sharing, possibility of chosing the sign of the X-axis) + +*/ +class energyCalibrationFunctions { + + public: + + energyCalibrationFunctions(int s=-1) {setScanSign(s);}; + + /** sets scan sign + \param s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets + \returns current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) + */ + int setScanSign(int s=0) {if (s==1 || s==-1) sign=s; return sign;};; + + +#ifdef MYROOT + /** + Gaussian Function with charge sharing pedestal + par[0] is the absolute height of the background pedestal + par[1] is the slope of the background pedestal + par[2] is the gaussian peak position + par[3] is the RMS of the gaussian (and of the pedestal) + par[4] is the height of the function + par[5] is the fractional height of the charge sharing pedestal (scales with par[3]) + */ + Double_t gaussChargeSharing(Double_t *x, Double_t *par); + + /** + Basic erf function + par[0] is the inflection point + par[1] is the RMS + par[2] is the amplitude + */ +Double_t erfFunction(Double_t *x, Double_t *par) ; + + /** Erf function with charge sharing slope + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) + */ +Double_t erfFunctionChargeSharing(Double_t *x, Double_t *par); + + /** Double Erf function with charge sharing slope + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point of the first energy + par[3] is the RMS of the first energy + par[4] is the amplitude of the first energy + par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) + par[6] is the inflection point of the second energy + par[7] is the RMS of the second energy + par[8] is the amplitude of the second energy + par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) + */ + +Double_t erfFuncFluo(Double_t *x, Double_t *par); + + + /** + static function Gaussian with charge sharing pedestal with the correct scan sign + par[0] is the absolute height of the background pedestal + par[1] is the fractional height of the charge sharing pedestal (scales with par[3] + par[2] is the gaussian peak position + par[3] is the RMS of the gaussian (and of the pedestal) + par[4] is the height of the function + */ + Double_t spectrum(Double_t *x, Double_t *par); + + + /** Erf function with charge sharing slope with the correct scan sign + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) + */ + Double_t scurve(Double_t *x, Double_t *par); + + + + /** Double Erf function with charge sharing slope + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point of the first energy + par[3] is the RMS of the first energy + par[4] is the amplitude of the first energy + par[5] is the angual coefficient of the charge sharing slope of the first energy (scales with par[3]) + par[6] is the inflection point of the second energy + par[7] is the RMS of the second energy + par[8] is the amplitude of the second energy + par[9] is the angual coefficient of the charge sharing slope of the second energy (scales with par[8]) + */ + Double_t scurveFluo(Double_t *x, Double_t *par); + +#endif + +/** Calculates the median of an array of n elements */ + static double median(double *x, int n); +/** Calculates the median of an array of n elements (swaps the arrays!)*/ + static int quick_select(int arr[], int n); +/** Calculates the median of an array of n elements (swaps the arrays!)*/ + static int kth_smallest(int *a, int n, int k); + + private: + int sign; + + +}; + +/** + class alowing the energy calibration of photon counting and anlogue detectors + +*/ + +class energyCalibration { + + + public: + /** + default constructor - creates the function with which the s-curves will be fitted + */ + energyCalibration(); + + /** + default destructor - deletes the function with which the s-curves will be fitted + */ + ~energyCalibration(); + + /** sets plot flag + \param p plot flag (-1 gets, 0 unsets, >0 plot) + \returns current plot flag + */ + int setPlotFlag(int p=-1) {if (p>=0) plot_flag=p; return plot_flag;}; + + /** sets scan sign + \param s can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) otherwise gets + \returns current scan sign can be 1 (energy and x-axis have the same direction) or -1 (energy and x-axis have opposite directions) + */ + int setScanSign(int s=0) {return funcs->setScanSign(s);}; + + /** sets plot flag + \param p plot flag (-1 gets, 0 unsets, >0 plot) + \returns current plot flag + */ + int setChargeSharing(int p=-1); + + + void fixParameter(int ip, Double_t val); + + void releaseParameter(int ip); + +#ifdef MYROOT + + static TH1F* createMedianHistogram(TH2F* h2, int ch0, int nch); + + + /** sets the s-curve fit range + \param mi minimum of the fit range (-1 is histogram x-min) + \param ma maximum of the fit range (-1 is histogram x-max) + */ + void setFitRange(Double_t mi, Double_t ma){fit_min=mi; fit_max=ma;}; + + /** gets the s-curve fit range + \param mi reference for minimum of the fit range (-1 is histogram x-min) + \param ma reference for maximum of the fit range (-1 is histogram x-max) + */ + void getFitRange(Double_t &mi, Double_t &ma){mi=fit_min; ma=fit_max;}; + + +/** set start parameters for the s-curve function + \param par parameters, -1 sets to auto-calculation + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive + */ + void setStartParameters(Double_t *par); + +/** get start parameters for the s-curve function + \param par parameters, -1 means auto-calculated + par[0] is the pedestal + par[1] is the slope of the pedestal + par[2] is the inflection point + par[3] is the RMS + par[4] is the amplitude + par[5] is the angual coefficient of the charge sharing slope (scales with par[3]) -- always positive + */ + void getStartParameters(Double_t *par); + + /** + fits histogram with the s-curve function + \param h1 1d-histogram to be fitted + \param mypar pointer to fit parameters array + \param emypar pointer to fit parameter errors + \returns the fitted function - can be used e.g. to get the Chi2 or similar + */ + TF1 *fitSCurve(TH1 *h1, Double_t *mypar, Double_t *emypar); + + + /** + fits histogram with the spectrum + \param h1 1d-histogram to be fitted + \param mypar pointer to fit parameters array + \param emypar pointer to fit parameter errors + \returns the fitted function - can be used e.g. to get the Chi2 or similar + */ + TF1 *fitSpectrum(TH1 *h1, Double_t *mypar, Double_t *emypar); + + + /** + calculates gain and offset for the set of inflection points + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param fl array of inflection points (nscan long) + \param efl array of errors on the inflection points (nscan long) + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \returns graph energy vs inflection point + */ + TGraphErrors* linearCalibration(int nscan, Double_t *en, Double_t *een, Double_t *fl, Double_t *efl, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff); + + /** + calculates gain and offset for the set of energy scans + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param h1 array of TH1 + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \returns graph energy vs inflection point + */ + TGraphErrors* calibrateScurves(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 1);}; + + /** + calculates gain and offset for the set of energy spectra + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param h1 array of TH1 + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \returns graph energy vs peak + */ + TGraphErrors* calibrateSpectra(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff){return calibrate(nscan, en, een, h1, gain, off, egain, eoff, 0);}; + + +#endif + private: + +#ifdef MYROOT + /** + calculates gain and offset for the set of energies + \param nscan number of energy scans + \param en array of energies (nscan long) + \param een array of errors on energies (nscan long) - can be NULL! + \param h1 array of TH1 + \param gain reference to gain resulting from the fit + \param off reference to offset resulting from the fit + \param egain reference to error on the gain resulting from the fit + \param eoff reference to the error on the offset resulting from the fit + \param integral 1 is an s-curve set (default), 0 spectra + \returns graph energy vs peak/inflection point + */ + TGraphErrors* calibrate(int nscan, Double_t *en, Double_t *een, TH1F **h1, Double_t &gain, Double_t &off, Double_t &egain, Double_t &eoff, int integral=1); + + + /** + Initializes the start parameters and the range of the fit depending on the histogram characteristics and/or on the start parameters specified by the user + \param fun pointer to function to be initialized + \param h1 histogram from which to extract the range and start parameters, if not already specified by the user + +*/ + + void initFitFunction(TF1 *fun, TH1 *h1); + + + /** + Performs the fit according to the flags specified and returns the fitted function + \param fun function to fit + \param h1 histogram to fit + \param mypar pointer to fit parameters array + \param emypar pointer to fit parameter errors + \returns the fitted function - can be used e.g. to get the Chi2 or similar + */ + TF1 *fitFunction(TF1 *fun, TH1 *h1, Double_t *mypar, Double_t *emypar); + +#endif + +#ifdef MYROOT + Double_t fit_min; /**< minimum of the s-curve fitting range, -1 is histogram x-min */ + Double_t fit_max; /**< maximum of the s-curve fitting range, -1 is histogram x-max */ + + Double_t bg_offset; /**< start value for the background pedestal */ + Double_t bg_slope; /**< start value for the background slope */ + Double_t flex; /**< start value for the inflection point */ + Double_t noise; /**< start value for the noise */ + Double_t ampl; /**< start value for the number of photons */ + Double_t cs_slope; /**< start value for the charge sharing slope */ + + + TF1 *fscurve; /**< function with which the s-curve will be fitted */ + + TF1 *fspectrum; /**< function with which the spectrum will be fitted */ + +#endif + + energyCalibrationFunctions *funcs; + int plot_flag; /**< 0 does not plot, >0 plots (flags?) */ + + int cs_flag; /**< 0 functions without charge sharing contribution, >0 with charge sharing contribution */ + +}; + +#endif + + + + + + + + + + + + + + + + + + + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyCalibrationMacro.C b/slsDetectorSoftware/slsDetectorAnalysis/energyCalibrationMacro.C new file mode 100644 index 000000000..5a4c4386f --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyCalibrationMacro.C @@ -0,0 +1,24 @@ +{ + + TH1F *h1[3]; + TH2F *h2=createScan("/scratch/stability_test/ag_source_S%d_10.raw",500,900,10,1280*2); + h1[0]=getCh(h2,500); + h1[1]=getCh(h2,300); + h1[2]=getCh(h2,700); + Double_t gain, offset, eg, eo; + Double_t en[3]={20,22,24}; + TH1F *h; + energyCalibration *e=new energyCalibration(); + e->setFitRange(500,700); + Double_t mypar[6]; + mypar[0]=0; //pedestal + mypar[1]=0; //pedestal slope + mypar[2]=-1; //inflection point - must be free for all energies and will be set at half of the scan range + mypar[3]=10; //noise rms + mypar[4]=1000; //number of photons + mypar[5]=0; //charge sharing slope + e->setFitParameters(mypar); + + TGraphErrors *gr=e->calibrate(3,en,NULL,h1,gain,offset,eg,eo); + +} diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp new file mode 100644 index 000000000..aa54cb2ed --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.cpp @@ -0,0 +1,591 @@ +#include "energyConversion.h" + +#include +#include +#include +#include + +#include "fileIOStatic.h" + +using namespace std; + + + + +int energyConversion::readCalibrationFile(string fname, double &gain, double &offset){ + + string str; + ifstream infile; +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + getline(infile,str); +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> offset >> gain; + infile.close(); + cout << "Calibration file loaded: " << fname << endl; + } else { + std::cout<< "Could not open calibration file "<< fname << std::endl; + gain=0.; + offset=0.; +#ifndef MYROOT + return FAIL; +#endif + return -1; + } +#ifndef MYROOT + return OK; +#endif + return 0; +}; + +int energyConversion::writeCalibrationFile(string fname, double gain, double offset){ + //std::cout<< "Function not yet implemented " << std::endl; + ofstream outfile; + outfile.open (fname.c_str()); + + // >> i/o operations here << + if (outfile.is_open()) { + outfile << offset << " " << gain << std::endl; + } else { + std::cout<< "Could not open calibration file "<< fname << " for writing" << std::endl; +#ifndef MYROOT + return FAIL; +#endif + return -1; + } + + outfile.close(); + +#ifndef MYROOT + return OK; +#endif + return 0; +}; + + +int energyConversion::readCalibrationFile(string fname, int *gain, int *offset, int64_t &tau, detectorType myDetectorType){ + + + + string str; + ifstream infile; + double o,g; + int ig=0; + switch (myDetectorType) { + case EIGER: + + + +#ifdef VERBOSE + std::cout<< "Opening file "<< fname << std::endl; +#endif + infile.open(fname.c_str(), ios_base::in); + if (infile.is_open()) { + //get gain and offset + for (ig=0; ig<4; ig++) { + //while ( (getline(infile,str)) > -1) { + getline(infile,str); +#ifdef VERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> o >> g; + offset[ig]=(int)(o*1000); + gain[ig]=(int)(g*1000); + // ig++; + if (ig>=4) + break; + } + //get tau + if (myDetectorType == EIGER) { + if(getline(infile,str)){ + istringstream ssstr(str); + ssstr >> tau; +#ifdef VERBOSE + std::cout<< "tau:" << tau << std::endl; +#endif + } + } + infile.close(); + cout << "Calibration file loaded: " << fname << endl; + } else { + cout << "Could not open calibration file: "<< fname << std::endl; + gain[0]=0; + offset[0]=0; +#ifndef MYROOT + return FAIL; +#endif + return -1; + } +#ifndef MYROOT + return OK; +#endif + return 0; + break; + default: + std::cout<< "Writing Calibration Files for this detector not defined\n" << std::endl; + return FAIL; + } + +}; + +int energyConversion::writeCalibrationFile(string fname, int *gain, int *offset, int64_t tau, detectorType myDetectorType){ + //std::cout<< "Function not yet implemented " << std::endl; + ofstream outfile; + switch (myDetectorType) { + case EIGER: + + outfile.open (fname.c_str()); + + // >> i/o operations here << + if (outfile.is_open()) { + for (int ig=0; ig<4; ig++) + outfile << ((double)offset[ig]/1000) << " " << ((double)gain[ig]/1000) << std::endl; + outfile << tau << std::endl; + } else { + std::cout<< "Could not open calibration file "<< fname << " for writing" << std::endl; +#ifndef MYROOT + return FAIL; +#endif + return -1; + } + + outfile.close(); +#ifndef MYROOT + return OK; +#endif + return 0; + break; + default: + std::cout<< "Writing Calibration Files for this detector not defined\n" << std::endl; + return FAIL; + } + +}; + + +#ifndef MYROOT + +/* I/O */ + + +slsDetectorDefs::sls_detector_module* energyConversion::readSettingsFile(string fname, detectorType myDetectorType, sls_detector_module *myMod, int* iodelay){ + + + + + int nflag=0; + + + if (myMod==NULL) { + myMod=createModule(myDetectorType); + nflag=1; + } + + int id=0,i; + string names[100]; + string myfname; + string str; + ifstream infile; + ostringstream oss; + int iline=0; + string sargname; + int ival; + int ichan=0, ichip=0, idac=0; + int nch=((myMod->nchan)/(myMod->nchip)); + + //ascii settings/trim file + switch (myDetectorType) { + case MYTHEN: + break; + case MOENCH: + names[id++]="Vdac0"; + names[id++]="Vdac1"; + names[id++]="Vdac2"; + names[id++]="Vdac3"; + names[id++]="Vdac4"; + names[id++]="Vdac5"; + names[id++]="Vdac6"; + names[id++]="Vdac7"; + break; + case GOTTHARD: + case PROPIX: + names[id++]="Vref"; + names[id++]="VcascN"; + names[id++]="VcascP"; + names[id++]="Vout"; + names[id++]="Vcasc"; + names[id++]="Vin"; + names[id++]="Vref_comp"; + names[id++]="Vib_test"; + break; + case EIGER: + break; + case JUNGFRAU: + names[id++]="VDAC0"; + names[id++]="VDAC1"; + names[id++]="VDAC2"; + names[id++]="VDAC3"; + names[id++]="VDAC4"; + names[id++]="VDAC5"; + names[id++]="VDAC6"; + names[id++]="VDAC7"; + names[id++]="VDAC8"; + names[id++]="VDAC9"; + names[id++]="VDAC10"; + names[id++]="VDAC11"; + names[id++]="VDAC12"; + names[id++]="VDAC13"; + names[id++]="VDAC14"; + names[id++]="VDAC15"; + break; + default: + cout << "Unknown detector type - unknown format for settings file" << endl; + return NULL; + } + +#ifdef VERBOSE + std::cout<< "reading settings file for module number "<< myMod->module << std::endl; +#endif + myfname=fname; +#ifdef VERBOSE + std::cout<< "file name is "<< myfname << std::endl; +#endif + + switch (myDetectorType) { + + case MYTHEN: + infile.open(myfname.c_str(), ios_base::in); + if (infile.is_open()) { + for (int iarg=0; iargndac; iarg++) { + getline(infile,str); + iline++; + istringstream ssstr(str); + ssstr >> sargname >> ival; +#ifdef VERBOSE + std::cout<< sargname << " dac nr. " << idac << " is " << ival << std::endl; +#endif + myMod->dacs[idac]=ival; + idac++; + } + for (ichip=0; ichipnchip; ichip++) { + getline(infile,str); + iline++; +#ifdef VERYVERBOSE + std::cout<< str << std::endl; +#endif + istringstream ssstr(str); + ssstr >> sargname >> ival; +#ifdef VERYVERBOSE + std::cout<< "chip " << ichip << " " << sargname << " is " << ival << std::endl; +#endif + + myMod->chipregs[ichip]=ival; + for (ichan=0; ichannChans <<" iline " << iline<< std::endl; +#endif + iline++; + myMod->chanregs[ichip*nch+ichan]=0; + for (int iarg=0; iarg<6 ; iarg++) { + ssstr >> ival; + //if (ssstr.good()) { + switch (iarg) { + case 0: +#ifdef VERYVERBOSE + std::cout<< "trimbits " << ival ; +#endif + myMod->chanregs[ichip*nch+ichan]|=ival&TRIMBITMASK; + break; + case 1: +#ifdef VERYVERBOSE + std::cout<< " compen " << ival ; +#endif + myMod->chanregs[ichip*nch+ichan]|=ival<<9; + break; + case 2: +#ifdef VERYVERBOSE + std::cout<< " anen " << ival ; +#endif + myMod->chanregs[ichip*nch+ichan]|=ival<<8; + break; + case 3: +#ifdef VERYVERBOSE + std::cout<< " calen " << ival ; +#endif + myMod->chanregs[ichip*nch+ichan]|=ival<<7; + break; + case 4: +#ifdef VERBOSE + std::cout<< " outcomp " << ival ; +#endif + myMod->chanregs[ichip*nch+ichan]|=ival<<10; + break; + case 5: +#ifdef VERBOSE + std::cout<< " counts " << ival << std::endl; +#endif + myMod->chanregs[ichip*nch+ichan]|=ival<<11; + break; + default: + std::cout<< " too many columns" << std::endl; + break; + } + } + } + // } + } +#ifdef VERBOSE + std::cout<< "read " << ichan*ichip << " channels" <dacs,sizeof(dacs_t)*(myMod->ndac)); + infile.read((char*) iodelay,sizeof(*iodelay)); + infile.read((char*) myMod->chanregs,sizeof(int)*(myMod->nchan)); +#ifdef VERBOSE + for(int i=0;indac;i++) + std::cout << "dac " << i << ":" << myMod->dacs[i] << std::endl; + std::cout << "iodelay:" << *iodelay << std::endl; +#endif + if(infile.eof()){ + cout<> sargname >> ival; + for (i=0;idacs[i]=ival; + idac++; +#ifdef VERBOSE + std::cout<< sargname << " dac nr. " << idac << " is " << ival << std::endl; +#endif + break; + } + } + } + if (i < id) { +#ifdef VERBOSE + std::cout<< sargname << " dac nr. " << idac << " is " << ival << std::endl; +#endif + }else + std::cout<< "Unknown dac " << sargname << std::endl; + + infile.close(); + strcpy(settingsFile,fname.c_str()); + cout << "Settings file loaded: " << settingsFile << endl; + return myMod; + + } + + //---------------------------------- + break; + + default: + std::cout<< "Unknown detector type - don't know how to read file" << myfname << std::endl; + infile.close(); + deleteModule(myMod); + return NULL; + + } + + std::cout<< "Error: Could not open settings file " << myfname << std::endl; + if (nflag) + deleteModule(myMod); + + return NULL; + + + +}; + + +int energyConversion::writeSettingsFile(string fname, detectorType myDetectorType, sls_detector_module mod, int* iodelay){ + + ofstream outfile; + + int nch=((mod.nchan)/(mod.nchip)); + + string names[100]; + int id=0; + switch (myDetectorType) { + case MYTHEN: + names[id++]="Vtrim"; + names[id++]="Vthresh"; + names[id++]="Rgsh1"; + names[id++]="Rgsh2"; + names[id++]="Rgpr"; + names[id++]="Vcal"; + names[id++]="outBuffEnable"; + break; + case MOENCH: + names[id++]="Vdac0"; + names[id++]="Vdac1"; + names[id++]="Vdac2"; + names[id++]="Vdac3"; + names[id++]="Vdac4"; + names[id++]="Vdac5"; + names[id++]="Vdac6"; + names[id++]="Vdac7"; + break; + case GOTTHARD: + case PROPIX: + names[id++]="Vref"; + names[id++]="VcascN"; + names[id++]="VcascP"; + names[id++]="Vout"; + names[id++]="Vcasc"; + names[id++]="Vin"; + names[id++]="Vref_comp"; + names[id++]="Vib_test"; + break; + case EIGER: + break; + case JUNGFRAU: + names[id++]="VDAC0"; + names[id++]="VDAC1"; + names[id++]="VDAC2"; + names[id++]="VDAC3"; + names[id++]="VDAC4"; + names[id++]="VDAC5"; + names[id++]="VDAC6"; + names[id++]="VDAC7"; + names[id++]="VDAC8"; + names[id++]="VDAC9"; + names[id++]="VDAC10"; + names[id++]="VDAC11"; + names[id++]="VDAC12"; + names[id++]="VDAC13"; + names[id++]="VDAC14"; + names[id++]="VDAC15"; + break; + default: + cout << "Unknown detector type - unknown format for settings file" << endl; + return FAIL; + } + + int iv, ichan, ichip; + int iv1, idac; + int nb; + + switch (myDetectorType) { + case EIGER: + outfile.open(fname.c_str(), ofstream::binary); + if (outfile.is_open()) { + iv = 1150; +#ifdef VERBOSE + for(int i=0;i>nb); + outfile << iv1 << " "; + nb=8; + iv1=((iv&(1<>nb); + outfile << iv1 << " "; + nb=7; + iv1=((iv&(1<>nb); + outfile <>nb); + outfile << iv1 << " "; + nb=11; + iv1= ((iv&0xfffff800)>>nb); + outfile << iv1 << std::endl; + } + } + } + outfile.close(); + return OK; + } + std::cout<< "could not open SETTINGS file " << fname << std::endl; + return FAIL; + + } + + +}; + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h new file mode 100644 index 000000000..027a78677 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/energyConversion.h @@ -0,0 +1,125 @@ +#ifndef ENERGYCONVERSION_H +#define ENERGYCONVERSION_H + +#ifdef __CINT__ +#define MYROOT +#define __cplusplus +#endif + +//#ifndef MYROOT +//#include "sls_receiver_defs.h" +#include "sls_detector_defs.h" +//#endif + +#include + +using namespace std; +/** + @short class handling the energy calibration and trim files IO +*/ + + +class energyConversion +//#ifndef MYROOT +: private virtual slsDetectorDefs + //#endif +{ + public: + /** default constrauctor */ + energyConversion(){}; + /** default destructor */ + virtual ~energyConversion(){}; + + + /** + reads a calibration file + \param fname file to be read + \param gain reference to the gain variable + \offset reference to the offset variable + */ + static int readCalibrationFile(string fname, double &gain, double &offset); + + /** + writes a calibration file + \param fname file to be written + \param gain + \param offset + */ + static int writeCalibrationFile(string fname, double gain, double offset); + + + + + /** + reads a calibration file + \param fname file to be read + \param gain reference to the gain variable + \offset reference to the offset variable + \tau tau + \tau tau + */ + static int readCalibrationFile(string fname, int *gain, int *offset, int64_t &tau, detectorType myDetectorType); + + /** + writes a calibration file + \param fname file to be written + \param gain + \param offset + \param tau + */ + static int writeCalibrationFile(string fname, int *gain, int *offset, int64_t tau, detectorType myDetectorType); + + + + + + + + + +#ifndef MYROOT + + /** + reads a trim/settings file + \param fname name of the file to be read + \param myDetectorType detector type (needed for number of channels, chips, dacs etc.) + \param myMod pointer to the module structure which has to be set.
If it is NULL a new module structure will be created + \param iodelay io delay (detector specific) + \returns the pointer to myMod or NULL if reading the file failed + */ + + sls_detector_module* readSettingsFile(string fname, detectorType myDetectorType, sls_detector_module* myMod=NULL, int* iodelay=0); + + /** + writes a trim/settings file + \param fname name of the file to be written + \param myDetectorType detector type (needed for number of channels, chips, dacs etc.) + \param mod module structure which has to be written to file + \param iodelay io delay (detector specific) + \returns OK or FAIL if the file could not be written + + \sa ::sls_detector_module mythenDetector::writeSettingsFile(string, sls_detector_module) + */ + int writeSettingsFile(string fname, detectorType myDetectorType, sls_detector_module mod, int* iodelay=0); + + /** allocates the momery for a detector module structure + \param myDetectorType detector type (needed for number of channels, chips, dacs etc.) + \returns pointer to detector module + */ + virtual sls_detector_module* createModule(detectorType myDetectorType)=0; + + /** + frees the memory of a detector module structure + \param myMod pointer to memeory to be freed + */ + virtual void deleteModule(sls_detector_module *myMod)=0; + + protected: + /** pointer to settings file name */ + char *settingsFile; + + +#endif + +}; +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/fileIO.cpp b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.cpp new file mode 100644 index 000000000..5ab0d033f --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.cpp @@ -0,0 +1,198 @@ +#include "fileIO.h" + + + + +/* I/O */ + +/* generates file name without extension*/ + +string fileIO::createFileName() { + currentFileName=fileIOStatic::createFileName(filePath, \ + fileName, \ + getActionMask(), \ + getCurrentScanVariable(0), \ + getScanPrecision(0), \ + getCurrentScanVariable(1), \ + getScanPrecision(1), \ + getCurrentPositionIndex(), \ + getNumberOfPositions(), \ + *fileIndex, \ + frameIndex, \ + detIndex \ + ); + + if (getDetectorsType()==JUNGFRAUCTB) { + nBytes=2*getTotalNumberOfChannels(); + } else + nBytes=getDataBytes(); + return currentFileName; + +} + + + +/* generates file prefix for receivers */ + +string fileIO::createReceiverFilePrefix() { + currentReceiverFilePrefix=fileIOStatic::createReceiverFilePrefix(fileName, \ + getActionMask(), \ + getCurrentScanVariable(0), \ + getScanPrecision(0), \ + getCurrentScanVariable(1), \ + getScanPrecision(1), \ + getCurrentPositionIndex(), \ + getNumberOfPositions(), \ + detIndex \ + ); + return currentReceiverFilePrefix; + +} + + + +/*writes raw data file */ + +int fileIO::writeDataFile(string fname, double *data, double *err, double *ang, char dataformat, int nch){ + if (nch==-1) + nch=getTotalNumberOfChannels(); + + cout << "Write filexxx...." << endl; + + return fileIOStatic::writeDataFile(fname, nch, data, err, ang, dataformat); + +} +int fileIO::writeDataFile(ofstream &outfile, double *data, double *err, double *ang, char dataformat, int nch, int offset){ + if (nch==-1) + nch=getTotalNumberOfChannels(); + + cout << "Write file...." << endl; + + return fileIOStatic::writeDataFile(outfile, nch, data, err, ang, dataformat, offset); + +} + + +int fileIO::writeDataFile(string fname, int *data){ + + return fileIOStatic::writeDataFile(fname, getTotalNumberOfChannels(), data); +} + + + + +int fileIO::writeDataFile(ofstream &outfile, int *data, int offset){ + + // cout << "Write raw file...." << endl; + return fileIOStatic::writeDataFile(outfile, getTotalNumberOfChannels(), data, offset); +} + + + +int fileIO::writeDataFile(void *data, int iframe) { + + if (iframe<0) + iframe=frameIndex; + + if ((*framesPerFile)<2) + iframe=-1; + + if ((iframe%(*framesPerFile))==0 || (iframe<0)) { + createFileName(); + filefd = fopen((currentFileName+string(".raw")).c_str(), "w"); + } + + if (filefd){ +// fileIOStatic::writeBinaryDataFile(filefd,getDataBytes(), data); + fileIOStatic::writeBinaryDataFile(filefd,nBytes, data); + iframe++; + } + + if ((iframe%(*framesPerFile)==0) || (iframe<0)) { + if (filefd) + fclose(filefd); + filefd=NULL; + } + return 0; +} + + + +int fileIO::closeDataFile() { + cout << "close file...." << endl; + if (filefd) + fclose(filefd); + filefd=NULL; + return 0; +} + + + + + +int fileIO::writeDataFile(string fname, short int *data){ + + cout << "Write raw file...." << endl; + return fileIOStatic::writeDataFile(fname, getTotalNumberOfChannels(), data); +} + + + + + + + + + +int fileIO::writeDataFile(ofstream &outfile, short int *data, int offset){ + + return fileIOStatic::writeDataFile(outfile, getTotalNumberOfChannels(), data, offset); +} + + + + + + + + + + +int fileIO::readDataFile(string fname, double *data, double *err, double *ang, char dataformat) { + return fileIOStatic::readDataFile(getTotalNumberOfChannels(), fname, data, err, ang, dataformat); + +} + +int fileIO::readDataFile(ifstream &infile, double *data, double *err, double *ang, char dataformat, int offset) { + return fileIOStatic::readDataFile(getTotalNumberOfChannels(), infile, data, err, ang, dataformat, offset); + +} + + + +int fileIO::readDataFile(string fname, int *data){ + + return fileIOStatic::readDataFile(fname, data, getTotalNumberOfChannels()); +}; + + +int fileIO::readDataFile(ifstream &infile, int *data, int offset){ + + return fileIOStatic::readDataFile(infile, data, getTotalNumberOfChannels(), offset); +}; + + + + + +int fileIO::readDataFile(string fname, short int *data){ + + return fileIOStatic::readDataFile(fname, data, getTotalNumberOfChannels()); +}; + + +int fileIO::readDataFile(ifstream &infile, short int *data, int offset){ + + return fileIOStatic::readDataFile(infile, data, getTotalNumberOfChannels(),offset); +}; + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/fileIO.h b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.h new file mode 100644 index 000000000..7091eb388 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/fileIO.h @@ -0,0 +1,326 @@ +#ifndef FILEIO_H +#define FILEIO_H + +#include "slsDetectorBase.h" +#include "fileIOStatic.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +/** + @short class handling the data file I/O flags +*/ + +class fileIO : public fileIOStatic, public virtual slsDetectorBase { + + + public: + + /* enum rawFileFormat { */ +/* ASCII, */ +/* BINARY */ +/* } */ + + + /** default constructor */ + fileIO(): fileIOStatic(){currentFrameIndex=-1;frameIndex=-1;detIndex=-1; framesPerFile=&nframes; nframes=1; filefd = NULL;}; + + /** virtual destructor */ + virtual ~fileIO(){}; + + using fileIOStatic::readDataFile; + using fileIOStatic::writeDataFile; + using fileIOStatic::createFileName; + + int getFileIndexFromFileName(string fname){return fileIOStatic::getFileIndexFromFileName(fname);}; + int getIndicesFromFileName(string fname, int &index){return fileIOStatic::getIndicesFromFileName(fname,index);}; + int getVariablesFromFileName(string fname, int &index, int &p_index, double &sv0, double &sv1){return fileIOStatic::getVariablesFromFileName(fname, index, p_index, sv0, sv1);}; + int getVariablesFromFileName(string fname, int &index, int &f_index, int &p_index, double &sv0, double &sv1, int &detindex){return fileIOStatic::getVariablesFromFileName(fname, f_index, index, p_index, sv0, sv1, detindex);}; + /** + sets the default output files path + \param s file path + \return actual file path + */ + virtual string setFilePath(string s) {sprintf(filePath, s.c_str()); return string(filePath);}; + + /** + sets the default output files root name + \param s file name to be set + \returns actual file name + */ + virtual string setFileName(string s) {sprintf(fileName, s.c_str()); return string(fileName);}; + + /** + sets the default output file index + \param i start file index to be set + \returns actual file index + */ + virtual int setFileIndex(int i) {*fileIndex=i; return *fileIndex;}; + + /** + sets the default output file frame index + \param i file frame index to be set + \returns actual file frame index + */ + virtual int setFrameIndex(int i) {frameIndex=i; return frameIndex;}; + + /** + sets the default output current frame index + \param i current frame index to be set + \returns actual current frame index + */ + virtual int setCurrentFrameIndex(int i) {currentFrameIndex=i; return currentFrameIndex;}; + + /** + sets the default output file index + \param i frame index to be set + \returns actual frame index + */ + virtual int setFramesPerFile(int i) {if (i>0) *framesPerFile=i; return *framesPerFile;}; + + /** + sets the default output file index + \param i detector index to be set + \returns actual detector index + */ + virtual int setDetectorIndex(int i) {detIndex=i;return detIndex;}; + + /** + \returns the output files path + + */ + virtual string getFilePath() {return string(filePath);}; + /** + \returns the output files root name + */ + virtual string getFileName() {return string(fileName);}; + + /** + \returns the output file index + */ + virtual int getFileIndex() {return *fileIndex;}; + + /** + \returns the output file frame index + */ + virtual int getFrameIndex() {return frameIndex;}; + + /** + \returns the output current frame index + */ + virtual int getCurrentFrameIndex() {return currentFrameIndex;}; + + /** + \returns the detector index + */ + virtual int getDetectorIndex() {return detIndex;}; + + /** + \returns the max frames per file + */ + virtual int getFramesPerFile() {return *framesPerFile;}; + + + string createFileName(); + + string createReceiverFilePrefix(); + + + /** + writes a data file + \param fname of the file to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector + \returns OK or FAIL if it could not write the file or data=NULL + */ + virtual int writeDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1); + + + /** + + writes a data file + \param outfile output file stream + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param nch number of channels to be written to file. if -1 defaults to the number of installed channels of the detector + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + + */ + virtual int writeDataFile(ofstream &outfile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int nch=-1, int offset=0); + + + /** + writes a data file + \param fname of the file to be written + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + */ + virtual int writeDataFile(string fname, int *data); + + + virtual int writeDataFile(void *data, int iframe=-1); + + int closeDataFile(); + /** + writes a data file + \param outfile output file stream + \param data array of data values + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + virtual int writeDataFile(ofstream &outfile, int *data, int offset=0); + + + + /** + writes a data file of short ints + \param fname of the file to be written + \param data array of data values + \returns OK or FAIL if it could not write the file or data=NULL + */ + virtual int writeDataFile(string fname, short int *data); + + + + + + + + /** + writes a data file of short ints + \param outfile output file stream + \param data array of data values + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + virtual int writeDataFile(ofstream &outfile, short int *data, int offset=0); + + + /** + reads a data file + \param fname of the file to be read + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \returns OK or FAIL if it could not read the file or data=NULL + */ + virtual int readDataFile(string fname, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'); + + /** + reads a data file + \param ifstream input file stream + \param data array of data values to be filled + \param err array of arrors on the data. If NULL no errors are expected on the file + + \param ang array of angular values. If NULL data are expected in the form chan-val(-err) otherwise ang-val(-err) + \param offset start channel number to be expected + \returns OK or FAIL if it could not read the file or data=NULL + */ + int readDataFile(ifstream& infile, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0); + + /** + reads a raw data file + \param fname of the file to be read + \param data array of data values + \returns OK or FAIL if it could not read the file or data=NULL +yes */ + virtual int readDataFile(string fname, int *data); + +/** + reads a raw data file + \param infile input file stream + \param data array of data values + \param offset first channel number to be expected + \returns OK or FAIL if it could not read the file or data=NULL + */ + int readDataFile(ifstream &infile, int *data, int offset=0); + + /** + + reads a short int raw data file + \param fname of the file to be read + \param data array of data values + \returns OK or FAIL if it could not read the file or data=NULL + */ + virtual int readDataFile(string fname, short int *data); + /** + reads a short int raw data file + \param infile input file stream + \param data array of data values + \param offset first channel number to be expected + \returns OK or FAIL if it could not read the file or data=NULL + */ + int readDataFile(ifstream &infile, short int *data, int offset=0); + + virtual int getDataBytes ( )=0; + friend class slsDetector; + + string getCurrentFileName(){return currentFileName;}; + protected: + + + void incrementFileIndex() { (*fileIndex)++; }; + + void incrementFrameIndex(int i) { frameIndex=frameIndex+i; }; + + void incrementCurrentFrameIndex() { (currentFrameIndex)++; }; + + void incrementDetectorIndex() { (detIndex)++; }; + + + string getCurrentReceiverFilePrefix(){return currentReceiverFilePrefix;}; + + + string currentFileName; + + string currentReceiverFilePrefix; + + + /** output directory */ + char *filePath; + /** file root name */ + char *fileName; + /** file index */ + int *fileIndex; + /** file frame index */ + int frameIndex; + /** current frame index */ + int currentFrameIndex; + /** detector id */ + int detIndex; + /** frames per file */ + int *framesPerFile; + + // int *fileFormat; + + private: + + + FILE *filefd; + ofstream fstream; + + int nframes; + // int fformat; + + + int nBytes; + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/fileIOStatic.h b/slsDetectorSoftware/slsDetectorAnalysis/fileIOStatic.h new file mode 100644 index 000000000..178f4b9b0 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/fileIOStatic.h @@ -0,0 +1,729 @@ +#ifndef FILEIO_STATIC_H +#define FILEIO_STATIC_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __CINT +#define MYROOT +#endif + +#include "sls_detector_defs.h" +using namespace std; +/** + @short class handling the data file I/O flags +*/ + +class fileIOStatic { + + + + + public: + /** default constructor */ + fileIOStatic(){}; + /** virtual de`structor */ + virtual ~fileIOStatic(){}; + + + + + /** generates file name without extension + + always appends to file path and file name the run index. + + in case also appends the position index and the two level of scan varaibles with the specified precision + + Filenames will be of the form: filepath/(dz_)filename(_Sy_sw_px_fv)_i + where z is the detector index, y is the scan0 variable, W is the scan 1 variable, x is the position index, v is the frame index and i is the run index + \param filepath outdir + \param filename file root name + \param aMask action mask (scans, positions) + \param sv0 scan variable 0 + \param prec0 scan precision 0 + \param sv1 scan variable 1 + \param prec1 scan precision 1 + \param pindex position index + \param npos number of positions + \param findex file index + \param frameindex frame index + \param detindex detector id + \returns file name without extension + */ + static string createFileName(char *filepath, char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos, int findex, int frameindex=-1, int detindex=-1){ \ + ostringstream osfn; \ + osfn << filepath << "/" << filename; \ + if ( aMask& (1 << (slsDetectorDefs::MAX_ACTIONS))) osfn << "_S" << fixed << setprecision(prec0) << sv0; \ + if (aMask & (1 << (slsDetectorDefs::MAX_ACTIONS+1))) osfn << "_s" << fixed << setprecision(prec1) << sv1; \ + if (pindex>0 && pindex<=npos) osfn << "_p" << pindex; \ + if(detindex>=0) osfn << "_d"<< detindex; \ + if(frameindex>=0) osfn << "_f" << frameindex; \ + osfn << "_" << findex; \ + return osfn.str(); \ + }; + + + /** generates file prefix for receivers without file path, frame index, file index or extension + + in case also appends the position index and the two level of scan varaibles with the specified precision + + File prefix will be of the form: (dz_)filename(_Sy_sw_px_) + where z is the detector index, y is the scan0 variable, W is the scan 1 variable and x is the position index + \param filename file root name + \param aMask action mask (scans, positions) + \param sv0 scan variable 0 + \param prec0 scan precision 0 + \param sv1 scan variable 1 + \param prec1 scan precision 1 + \param pindex position index + \param npos number of positions + \param detindex detector id + \returns file name without extension + */ + static string createReceiverFilePrefix(char *filename, int aMask, double sv0, int prec0, double sv1, int prec1, int pindex, int npos,int detindex=-1){ \ + ostringstream osfn; \ + osfn << filename; \ + if ( aMask& (1 << (slsDetectorDefs::MAX_ACTIONS))) osfn << "_S" << fixed << setprecision(prec0) << sv0; \ + if (aMask & (1 << (slsDetectorDefs::MAX_ACTIONS+1))) osfn << "_s" << fixed << setprecision(prec1) << sv1; \ + if (pindex>0 && pindex<=npos) osfn << "_p" << pindex; \ + if(detindex!=-1) osfn << "_d"<< detindex; \ + return osfn.str(); \ + }; + + + /** static function that returns the file index from the file name + \param fname file name + \returns file index + */ + static int getFileIndexFromFileName(string fname){ \ + int i; \ + size_t dot=fname.rfind("."); \ + if (dot==string::npos) \ + return -1; \ + size_t uscore=fname.rfind("_"); \ + if (uscore==string::npos) return -1; \ + if (sscanf( fname.substr(uscore+1,dot-uscore-1).c_str(),"%d",&i)) return i; \ + cout << "******************************** cannot parse file index" << endl; \ + return 0; \ + }; + + /** static function that returns the frame index and file index from the file name + \param fname file name + \param index reference to index + \returns frame index + */ + static int getIndicesFromFileName(string fname,int &index){ \ + int i; \ + string s; \ + size_t uscore=fname.rfind("_"); \ + if (uscore==string::npos) return -1; \ + s=fname; \ + if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)){ \ + index=i; \ + s=fname.substr(0,uscore); \ + } \ + /*else cout << "******************************** cannot parse file index" << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"f%d",&i)){ \ + if(i==-1)return 0; \ + else return i; } \ + /*cout << "******************************** cannot parse frame index" << endl; \*/ + return 0; \ + }; + + + /** static function that returns the variables from the file name + \param fname file name + \param index reference to index + \param p_index reference to position index + \param sv0 reference to scan variable 0 + \param sv1 reference to scan variable 1 + \returns file index + */ + static int getVariablesFromFileName(string fname, int &index, int &p_index, double &sv0, double &sv1) { \ + int i; \ + double f; \ + string s; \ + index=-1; \ + p_index=-1; \ + sv0=-1; \ + sv1=-1; \ + size_t uscore=fname.rfind("_"); \ + if (uscore==string::npos) return -1; \ + s=fname; \ + if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)) { \ + index=i; \ + s=fname.substr(0,uscore); \ + } \ + /* else cout << "Warning: ******************************** cannot parse file index from " << s << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"f%d",&i)) \ + s=fname.substr(0,uscore); \ + /*else cout << "Warning: ******************************** cannot parse frame index from " << s << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"d%d",&i)) \ + s=fname.substr(0,uscore); \ + /* else cout << "Warning: ******************************** cannot parse detector index from " << s << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"p%d",&i)) { \ + p_index=i; \ + s=fname.substr(0,uscore); \ + } \ + /* else cout << "Warning: ******************************** cannot parse position index from " << s << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"s%lf",&f)) { \ + sv1=f; \ + s=fname.substr(0,uscore); \ + } \ + /* else cout << "Warning: ******************************** cannot parse scan varable 1 from " << s << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"S%lf",&f)) { \ + sv0=f; \ + } \ + /* else cout << "Warning: ******************************** cannot parse scan varable 0 from " << s << endl; \*/ + return index; \ + }; + + + /** static function that returns the variables from the file name + \param fname file name + \param index reference to index + \param f_index reference to frame index + \param p_index reference to position index + \param sv0 reference to scan variable 0 + \param sv1 reference to scan variable 1 + \param detindex reference to detector id + \returns file index + */ + static int getVariablesFromFileName(string fname, int &index, int &f_index, int &p_index, double &sv0, double &sv1, int &detindex) { \ + int i; \ + double f; \ + string s; \ + index=-1; \ + p_index=-1; \ + sv0=-1; \ + sv1=-1; \ + size_t uscore=fname.rfind("_"); \ + if (uscore==string::npos) return -1; \ + s=fname; \ + if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)) { \ + index=i; \ + s=fname.substr(0,uscore); \ + } \ + /*else cout << "Warning: ******************************** cannot parse file index" << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"f%d",&i)) { \ + f_index=i; \ + s=fname.substr(0,uscore); \ + } \ + /*else cout << "Warning: ******************************** cannot parse frame index" << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"d%d",&i)) { \ + detindex=i; \ + s=fname.substr(0,uscore); \ + } \ + /* else cout << "Warning: ******************************** cannot parse detector id" << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"p%d",&i)) { \ + p_index=i; \ + s=fname.substr(0,uscore); \ + } \ + /*else cout << "Warning: ******************************** cannot parse position index" << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"s%lf",&f)) { \ + sv1=f; \ + s=fname.substr(0,uscore); \ + } \ + /*else cout << "Warning: ******************************** cannot parse scan varable 1" << endl; \*/ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"S%lf",&f)) { \ + sv0=f; \ + s=fname.substr(0,uscore); \ + } \ + /*else cout << "Warning: ******************************** cannot parse scan varable 0" << endl; \*/ + + return index; \ + }; + + + /** static function that verifies if the new file name containing new parameters matches all the given parameters + \param fname new complete file name prefix + \param index reference to index + \param f_index reference to frame index + \param p_index reference to position index + \param sv0 reference to scan variable 0 + \param sv1 reference to scan variable 1 + \param detindex reference to detector id + \returns file name + */ + static int verifySameFrame(string fname, int index, int f_index, int p_index, double sv0, double sv1, int detindex) { \ + int new_index=-1; + int new_f_index=-1; + int new_p_index=-1; + int new_det_index=-1; + double new_sv0=-1; + double new_sv1=-1; + getVariablesFromFileName(fname,new_index, new_f_index, new_p_index, new_sv0, new_sv1, new_det_index); + if(index!=new_index) return 0; + if(f_index!=new_f_index) return 0; + if(p_index!=new_p_index) return 0; + if(sv0!=new_sv0) return 0; + if(sv1!=new_sv1) return 0; + return 1; + } + + + /** static function that returns the name variable from the receiver complete file name prefix + \param fname complete file name prefix + \returns file name + */ + static string getNameFromReceiverFilePrefix(string fname) { \ + int i; \ + double f; \ + string s; \ + s=fname; \ + size_t uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"d%d",&i)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"p%d",&i)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"s%lf",&f)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"S%lf",&f)) \ + s=fname.substr(0,uscore); \ + + + return s; \ + }; + + + + + /** static function that returns the entire filename ithout file name prefix, detector index or extension + This will be concatenated with all the other detector file names for the gui + \param fname complete file name + \returns file name without file name prefix, detector index or extension + */ + static string getReceiverFileNameToConcatenate(string fname) { \ + int i;double f; \ + string s=fname; \ + if(fname.empty()) return fname; \ + size_t dot=s.find("."); + size_t uscore=s.rfind("_"); \ + + if (uscore==string::npos) return "??"; \ + if (sscanf(s.substr(uscore+1,s.size()-uscore-1).c_str(),"%d",&i)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"f%d",&i)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"d%d",&i)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"p%d",&i)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"s%lf",&f)) \ + s=fname.substr(0,uscore); \ + uscore=s.rfind("_"); \ + if (sscanf( s.substr(uscore+1,s.size()-uscore-1).c_str(),"S%lf",&f)) \ + s=fname.substr(0,uscore); \ + return(fname.substr(s.size(),dot-s.size()));\ + \ + }; + + + + + /** + + writes a data file + \param fname of the file to be written + \param nch number of channels to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double + \returns OK or FAIL if it could not write the file or data=NULL + + */ + + static int writeDataFile(string fname, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f'){ \ + ofstream outfile; \ + if (data==NULL) { \ + cout << "No data to write!" << endl; \ + return slsDetectorDefs::FAIL; \ + } \ + outfile.open (fname.c_str(),ios_base::out); \ + if (outfile.is_open()) { \ + writeDataFile(outfile, nch, data, err, ang, dataformat, 0); \ + outfile.close(); \ + return slsDetectorDefs::OK; \ + } else { \ + std::cout<< "Could not open file " << fname << "for writing"<< std::endl; \ + return slsDetectorDefs::FAIL; \ + } \ + }; + + + + + /** + writes a data file + \param outfile output file stream + \param nch number of channels to be written + \param data array of data values + \param err array of arrors on the data. If NULL no errors will be written + \param ang array of angular values. If NULL data will be in the form chan-val(-err) otherwise ang-val(-err) + \param dataformat format of the data: can be 'i' integer or 'f' double (default) + \param offset start channel number + \returns OK or FAIL if it could not write the file or data=NULL + */ + static int writeDataFile(ofstream &outfile, int nch, double *data, double *err=NULL, double *ang=NULL, char dataformat='f', int offset=0){ + int idata; \ + if (data==NULL || nch==0) { \ + cout << "No data to write!" << endl; \ + return slsDetectorDefs::FAIL; \ + } \ + for (int ichan=0; ichan> ichan >> fdata; \ + if (ssstr.fail() || ssstr.bad()) { \ + interrupt=1; \ + break; \ + } \ + ich=iline; \ + if (ichan> fang >> fdata; \ + ich=iline; \ + } \ + if (ssstr.fail() || ssstr.bad()) { \ + interrupt=1; \ + break; \ + } \ + if (err) \ + ssstr >> ferr; \ + if (ssstr.fail() || ssstr.bad()) { \ + interrupt=1; \ + break; \ + } \ + if (ich=nch) { \ + interrupt=1; \ + break; \ + } \ + } \ + return iline; \ + }; + + + /** + reads a raw data file + \param fname of the file to be read + \param data array of data values + \param nch number of channels + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(string fname, int *data, int nch) { \ + ifstream infile; \ + int iline=0; \ + string str; \ + infile.open(fname.c_str(), ios_base::in); \ + if (infile.is_open()) { \ + iline=readDataFile(infile, data, nch, 0); \ + infile.close(); \ + } else { \ + std::cout<< "Could not read file " << fname << std::endl; \ + return -1; \ + } \ + return iline; \ + }; + + + /** + reads a raw data file + \param infile input file stream + \param data array of data values + \param nch number of channels + \param offset start channel value + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(ifstream &infile, int *data, int nch, int offset) { \ + int ichan, idata, iline=0; \ + int interrupt=0; \ + string str; \ + while (infile.good() and interrupt==0) { \ + getline(infile,str); \ + istringstream ssstr(str); \ + ssstr >> ichan >> idata; \ + if (ssstr.fail() || ssstr.bad()) { \ + interrupt=1; \ + break; \ + } \ + if (iline=offset) { \ + data[iline]=idata; \ + iline++; \ + } \ + } else { \ + interrupt=1; \ + break; \ + } \ + } \ + return iline; \ + }; + + /** + reads a short int rawdata file + \param name of the file to be read + \param data array of data values + \param nch number of channels + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(string fname, short int *data, int nch){ \ + ifstream infile; \ + int iline=0; \ + string str; \ + infile.open(fname.c_str(), ios_base::in); \ + if (infile.is_open()) { \ + iline=readDataFile(infile, data, nch, 0); \ + infile.close(); \ + } else { \ + std::cout<< "Could not read file " << fname << std::endl; \ + return -1; \ + } \ + return iline; \ + }; + + /** + reads a short int raw data file + \param infile input file stream + \param data array of data values + \param nch number of channels + \param offset start channel value + \returns OK or FAIL if it could not read the file or data=NULL + */ + static int readDataFile(ifstream &infile, short int *data, int nch, int offset) { \ + int ichan, iline=0; \ + short int idata; \ + int interrupt=0; \ + string str; \ + while (infile.good() and interrupt==0) { \ + getline(infile,str); \ + istringstream ssstr(str); \ + ssstr >> ichan >> idata; \ + if (ssstr.fail() || ssstr.bad()) { \ + interrupt=1; \ + break; \ + } \ + if (iline=offset) { \ + data[iline]=idata; \ + iline++; \ + } \ + } else { \ + interrupt=1; \ + break; \ + } \ + return iline; \ + }; \ + return iline; \ + }; +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/movingStat.h b/slsDetectorSoftware/slsDetectorAnalysis/movingStat.h new file mode 100644 index 000000000..d6a2b2e33 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/movingStat.h @@ -0,0 +1,147 @@ + /********************************************//** + * @file movingStat.h + * @short handles pedestal data and moves accordingly + ***********************************************/ +#ifndef MOVINGSTAT_H +#define MOVINGSTAT_H + +//#include "sls_detector_defs.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + + +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; + + +/** + @short class handling pedestal data and moves according to data + */ + +class movingStat{ + +public: + /** + * Constructor + */ + movingStat() : n(0), m_n(0), m_oldM(0), m_newM(0), m_oldM2(0), m_newM2(0){} + + /** + * Clear number of data values + */ + inline void Clear(){ + m_n = 0; + } + + /** + * Set Pedestal + */ + inline void SetN(int i) {n=i;}; + + /** + * Get Pedestal + */ + inline int GetN() {return n;}; + + /** + * Calculate Pedestal + */ + inline void Calc(double x) { + if (m_n 0) ? m_newM/m_n : 0.0; + } + + /** + * Get mean 2 + */ + inline double M2() const{ + return ( (m_n > 1) ? m_newM2/m_n : 0.0 ); + } + + /** + * Get variance + */ + inline double Variance() const{ + return ( (m_n > 1) ? (M2()-Mean()*Mean()) : 0.0 ); + } + + /** + * Get standard deviation + */ + inline double StandardDeviation() const{ + return ( (Variance() > 0) ? sqrt( Variance() ) : -1 ); + } + +private: + /** pedestal */ + int n; + /** number of data values */ + int m_n; + + /** old and new mean */ + double m_oldM, m_newM, m_oldM2, m_newM2; +}; + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.cpp b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.cpp new file mode 100644 index 000000000..6bcfbb24e --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.cpp @@ -0,0 +1,995 @@ +#include "postProcessing.h" +#include "postProcessingFuncs.h" +#include "angleConversionConstant.h" +#ifdef VERBOSE +#include "usersFunctions.h" +#elif EXTPP +#include "usersFunctions.h" +#endif + +//#define VERBOSE + +static void* startProcessData(void *n){ + postProcessing *myDet=(postProcessing*)n; + myDet->processData(1); + pthread_exit(NULL); + +}; + +static void* startProcessDataNoDelete(void *n){ + postProcessing *myDet=(postProcessing*)n; + myDet->processData(0); + pthread_exit(NULL); + +}; + + + +postProcessing::postProcessing(): expTime(NULL), ang(NULL), val(NULL), err(NULL), numberOfChannels(0), badChannelMask(NULL){ + pthread_mutex_t mp1 = PTHREAD_MUTEX_INITIALIZER; + mp=mp1; + pthread_mutex_init(&mp, NULL); + mg=mp1; + pthread_mutex_init(&mg, NULL); + ms=mp1; + pthread_mutex_init(&ms, NULL); + + //cout << "reg callback "<< endl; + dataReady = 0; + pCallbackArg = 0; + //cout << "done "<< endl; + rawDataReady = 0; + pRawDataArg = 0; + + + //#ifdef VERBOSE + // registerDataCallback(&defaultDataReadyFunc, NULL); + //#endif +#ifdef EXTPP + registerRawDataCallback(&defaultRawDataReadyFunc, NULL); +#endif + + ppFun=new postProcessingFuncs(); + +} + + + + + +postProcessing::~postProcessing(){ + delete ppFun; +}; + + + + + + + + +void postProcessing::processFrame(int *myData, int delflag, int jctb) { + + string fname; + //double *fdata=NULL; + +#ifdef VERBOSE + cout << "start processing"<< endl; +#endif + + incrementProgress(); + +#ifdef VERBOSE + cout << "prog incremented"<< endl; +#endif + + /** decode data */ + + // if (getDetectorsType()==MYTHEN) { + fdata=decodeData(myData, fdata); + +#ifdef VERBOSE + cout << "decode"<< endl; +#endif + // } else + // fdata=NULL; + + if (rawDataReady) { + #ifdef VERBOSE + cout << "raw data ready..." << endl; + #endif + rawDataReady(fdata,numberOfChannels, pRawDataArg); +#ifdef VERBOSE + cout << "done" << endl; + cout << "NO FILE WRITING AND/OR DATA PROCESSING DONE BY SLS DETECTOR SOFTWARE!!!" << endl; +#endif + } else { + + + pthread_mutex_lock(&mp); + fname=createFileName(); + pthread_mutex_unlock(&mp); +#ifdef VERBOSE + cout << "fname is " << fname << endl; +#endif + + //Checking for write flag + if((*correctionMask)&(1<=0){ + if (getDetectorsType()==MYTHEN) + incrementFrameIndex(1); + else if((currentFrameIndex%getFramesPerFile())==0) + incrementFrameIndex(getFramesPerFile()); + } + + + + + if (fdata) + delete [] fdata; + fdata=NULL; + + + // if (jctb==0) { + delete [] myData; + myData=NULL; + +#ifdef VERBOSE + cout << "Pop data queue " << *fileIndex << endl; +#endif + + popDataQueue(); //remove the data from the queue + +#ifdef VERBOSE + cout << "Data queue popped" << endl; +#endif + + +#ifdef VERBOSE + cout << "process frame returning " << endl; +#endif + // } + +} + + + + +void postProcessing::doProcessing(double *lfdata, int delflag, string fname) { + + #ifdef VERBOSE + cout << "??????????????????????????????????????????? do processing - data size is " << arraySize << endl; + #endif + + + int np; + +#ifdef VERBOSE + cout << "arrays allocated " << endl; +#endif + int npos=getNumberOfPositions(); + + string ext=".dat"; + +#ifdef VERBOSE + cout << "npos is "<< npos << endl; +#endif + + double t=0; + + if (expTime) + t=(*expTime)*1E-9; + else + cout << "no pointer to exptime" << endl; +#ifdef VERBOSE + cout << "exptime is "<< t << endl; +#endif + + if (GetCurrentPositionIndex()<=1 || npos<2) { +#ifdef VERBOSE + cout << "init dataset" << endl; +#endif + + + if (*correctionMask&(1<< ANGULAR_CONVERSION)) + ang=new double[arraySize]; + else + ang=NULL; + + val=new double[arraySize]; + err=new double[arraySize]; + + initDataset(0); + } + +#ifdef VERBOSE + cout << "add frame" << endl; +#endif + + /**ot them +start processing +prog incremented +decode +fname is //run_f0_0 +??????????????????????????????????????????? do processing - data size is 30720 +arrays allocated +npos is 0 +exptime is 10.00 +init dataset +add frame +data queue size lock +data queue size unlock + **/ + + addFrame(lfdata,currentPosition, currentI0, t, fname, 0); + // cout << "++++++++++++++++++++" << GetCurrentPositionIndex() << " " << npos << " " << positionFinished() << " " << dataQueueSize() << endl; + if ((GetCurrentPositionIndex()>=npos && dataQueueSize()) || npos<2) { + //&& + + while(positionFinished()==0 && npos>1) { + ; + } +#ifdef VERBOSE + cout << "finalize dataset" << endl; +#endif + + finalizeDataset(ang, val, err, np); + //if (npos<2) { + IncrementPositionIndex(); + + pthread_mutex_lock(&mp); + fname=createFileName(); + pthread_mutex_unlock(&mp); + //} + + if((*correctionMask)&(1<0) { + + int *badChansList=new int[nbad]; + #ifdef VERBOSE + cout << "get badch array " << nbad << endl; + #endif + getBadChannelCorrection(badChansList); + #ifdef VERBOSE + cout << "done " << nbad << endl; + #endif + + if (badChannelMask) + delete [] badChannelMask; + + +#ifdef VERBOSE + cout << " nchans " << getTotalNumberOfChannels() << endl; +#endif + + badChannelMask=new int[getTotalNumberOfChannels()]; + +#ifdef VERBOSE + cout << " pointer to bad channel mask is " << badChannelMask << endl; +#endif + for (int ichan=0; ichan=0 ) { + if (badChannelMask[badChansList[ichan]]==0) { + badChannelMask[badChansList[ichan]]=1; + // cout << "bad: " << ichan << " " << badChansList[ichan] << endl; + } else + nbad--; + } + } + delete [] badChansList; + + } else { + if (badChannelMask) { +#ifdef VERBOSE + cout << "deleting bad channel mask beacuse number of bad channels is 0" << endl; +#endif + + delete [] badChannelMask; + badChannelMask=NULL; + } + } + + } else { +#ifdef VERBOSE + cout << "bad channel correction is disabled " << nbad << endl; +#endif + if (badChannelMask) { +#ifdef VERBOSE + cout << "deleting bad channel mask beacuse no bad channel correction is selected" << endl; +#endif + delete [] badChannelMask; + badChannelMask=NULL; + } + } + +#ifdef VERBOSE + cout << "number of bad channels is " << nbad << endl; +#endif + return nbad; + +} + + + + + + +void* postProcessing::processData(int delflag) { + if(setReceiverOnline()==OFFLINE_FLAG){ + +#ifdef VERBOSE + std::cout<< " ??????????????????????????????????????????? processing data - threaded mode " << *threadedProcessing << endl; +#endif + + + + + queuesize=dataQueueSize(); + + + int *myData; + char *p; + int dum=1; + int nf=1, ii, nch; + int jctb=0; + + +// if (getDetectorsType()==JUNGFRAUCTB) { +// nch=getTotalNumberOfChannels(); +// nf= getDataBytes()/(nch*2); +// cout << "WILL PROCESS " << nf << "SAMPLES AND " << nch <<"CHANNELS PER FRAME!" << endl; +// jctb=1; +// }// else +// // cout << "NOOT A JCTB" << endl; + + fdata=NULL; + + while(dum | *threadedProcessing) { // ???????????????????????? + /* IF THERE ARE DATA PROCESS THEM*/ + // cout << "loop" << endl; + while((queuesize=dataQueueSize())>0) { + /** Pop data queue */ + //#ifdef VERBOSE + cout << "data found"<< endl< 0){ +#ifdef VERY_VERY_DEBUG + if(acquiringDone == 1) cout << "acquiring seems to be done" << endl; +#endif + + + //IF GUI, check for last frames (counter upto 5) + if(dataReady){ + pthread_mutex_lock(&mg); + acquiringDone++; + pthread_mutex_unlock(&mg); +#ifdef VERY_VERY_DEBUG + cout << "acquiringDone :" << acquiringDone << endl; +#endif + } + + + //post to stopReceiver in acquire(), but continue reading frames + if (!dataReady || (acquiringDone >= 5)){ + if(!dataReady || (!nthframe) ||(!newData)){ +#ifdef VERY_VERY_DEBUG + cout << "gonna post for it to end" << endl; +#endif + sem_post(&sem_queue); +#ifdef VERY_VERY_DEBUG + cout << "Sem posted" << endl; +#endif + } + } + } + //random reads and for nthframe, checks if there is no new data + else if((!nthframe) ||(!newData)){ + //cout <<"cecking now" << endl; + if (checkJoinThread()){ + break; + } + } + + + + + + //for random reads, ask only if it has new data + if(!newData){ + if(caught > progress){ + newData = true; + + // If new data and acquiringDone>0 (= det acq over), reset to get more frames + if(dataReady && (acquiringDone > 0)){ + pthread_mutex_lock(&mg); + acquiringDone = 1; +#ifdef VERY_VERY_DEBUG + cout << "Keeping acquiringDone at 1 " << endl; +#endif + pthread_mutex_unlock(&mg); + } + + } + } + + + + if(newData){ +#ifdef VERY_VERY_DEBUG + cout << "new data" << endl; +#endif + //no gui + if (!dataReady){ + progress = caught; +#ifdef VERY_VERY_DEBUG + cout << "progress:" << progress << endl; +#endif + newData = false; +#ifdef VERY_VERY_DEBUG + cout << "newData set to false" << endl; +#endif + } + //gui + else{ + pthread_mutex_lock(&mg); + if(setReceiverOnline()==ONLINE_FLAG){ + //get data + strcpy(currentfName,""); + //int* receiverData = new int [getTotalNumberOfChannels()]; + int* receiverData = readFrameFromReceiver(currentfName,currentAcquisitionIndex,currentFrameIndex,currentSubFrameIndex); + + //if detector returned null + if(setReceiverOnline()==OFFLINE_FLAG) + receiverData = NULL; + + //no data or wrong data for print out + if(receiverData == NULL){ + currentAcquisitionIndex = -1; + cout<<"****Detector Data returned is NULL***"< progress){ +#ifdef VERY_VERY_DEBUG + cout << "GOT data" << endl; +#endif + fdata = decodeData(receiverData); + delete [] receiverData; + if ((fdata) && (dataReady)){ + // cout << "DATAREADY 3" << endl; + thisData = new detectorData(fdata,NULL,NULL,getCurrentProgress(),currentfName,nx,ny); + dataReady(thisData, currentFrameIndex, currentSubFrameIndex, pCallbackArg); + delete thisData; + fdata = NULL; + progress = caught; +#ifdef VERY_VERY_DEBUG + cout << "progress:" << progress << endl; +#endif + newData = false; +#ifdef VERY_VERY_DEBUG + cout << "newData set to false" << endl; +#endif + } + } + } + pthread_mutex_unlock(&mg); + } + } + + } + } + + return 0; +} + + + +int postProcessing::checkJoinThread() { + int retval; + pthread_mutex_lock(&mp); + retval=jointhread; + pthread_mutex_unlock(&mp); + return retval; +} + +void postProcessing::setJoinThread( int v) { + pthread_mutex_lock(&mp); + jointhread=v; + pthread_mutex_unlock(&mp); +} + +int* postProcessing::dataQueueFront() { + int *retval=NULL; + pthread_mutex_lock(&mp); + if( !dataQueue.empty() ) { + retval=dataQueue.front(); + } + pthread_mutex_unlock(&mp); + return retval; +} +int postProcessing::dataQueueSize() { + int retval; + +#ifdef VERBOSE + cout << "data queue size lock" << endl; +#endif + + + pthread_mutex_lock(&mp); + retval=dataQueue.size(); + pthread_mutex_unlock(&mp); +#ifdef VERBOSE + cout << "data queue size unlock" << endl; +#endif + + return retval; +} + + + +int* postProcessing::popDataQueue() { + int *retval=NULL; +#ifdef VERBOSE + cout << "Pop data queue lock" << endl; +#endif + + pthread_mutex_lock(&mp); + if( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + } + queuesize=dataQueue.size(); + pthread_mutex_unlock(&mp); +#ifdef VERBOSE + cout << "Pop data queue lock" << endl; +#endif + return retval; +} + +// detectorData* postProcessing::popFinalDataQueue() { +// detectorData *retval=NULL; +// pthread_mutex_unlock(&mg); +// if( !finalDataQueue.empty() ) { +// retval=finalDataQueue.front(); +// finalDataQueue.pop(); +// } +// pthread_mutex_unlock(&mg); +// return retval; +// } + +void postProcessing::resetDataQueue() { + int *retval=NULL; + pthread_mutex_lock(&mp); + while( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + delete [] retval; + } + pthread_mutex_unlock(&mp); + +} + +// void postProcessing::resetFinalDataQueue() { +// detectorData *retval=NULL; +// pthread_mutex_lock(&mg); +// while( !finalDataQueue.empty() ) { +// retval=finalDataQueue.front(); +// finalDataQueue.pop(); +// delete retval; +// } +// pthread_mutex_unlock(&mg); +// } +void postProcessing::initDataset(int r) { + + if (r) { + + int nmod=getNMods(); + int *chPM=new int[nmod]; + int *mM=new int[nmod]; + int totch=0; +#ifdef VERBOSE + cout << "init dataset stuff" << endl; +#endif + + for (int im=0; imr_conversion; + angOff[im]=p->offset; + angCenter[im]=p->center; + +#ifdef VERBOSE + cout << im << " " << angCenter[im] << " " << angRad[im] << " " << angOff[im] << endl; +#endif + + + } + sx=getAngularConversionParameter(SAMPLE_X); + sy=getAngularConversionParameter(SAMPLE_Y); + + } + + +#ifdef VERBOSE + cout << "init dataset" << endl; +#endif + // cout << "pp bad channel mask " << badChannelMask << endl; + fillBadChannelMask(); + // cout << "pp bad channel mask " << badChannelMask << endl; + + //cout << "EEEEEEEEEEEEEEEEEEEE init dataset " << endl; + ppFun->initDataset(&nmod,chPM,mM,badChannelMask, ffcoeff, fferr, &tdead, &angdir, angRad, angOff, angCenter, &to, &bs, &sx, &sy); + +#ifdef VERBOSE + cout << "done" << endl; +#endif + + + if (*correctionMask&(1<< ANGULAR_CONVERSION)) { + arraySize=getNumberOfAngularBins(); + if (arraySize<=0) + arraySize=totch; + } else { + arraySize=totch; + } + + numberOfChannels=totch; + + queuesize=dataQueueSize(); + + // resetFinalDataQueue(); + resetDataQueue(); + + + } else { + + // cout << "EEEEEEEEEEEEEEEEEEEE init dataset XXXX " << endl; + + ppFun->initDataset(); + + + } + +} + + + + + + +void postProcessing::addFrame(double *data, double pos, double i0, double t, string fname, double var) { + // cout << "EEEEEEEEEEEEEEEEEEEE add frame " << pos << " " << i0 << endl; + + if (*correctionMask&(1<< I0_NORMALIZATION)) + ppFun->addFrame(data, &pos, &i0, &t, fname.c_str(), &var); + else + ppFun->addFrame(data, &pos,NULL, &t, fname.c_str(), &var); + + + +} + +void postProcessing::finalizeDataset(double *a, double *v, double *e, int &np) { + + // cout << "EEEEEEEEEEEEEEEEEEEE finalize dataset " << endl; + ppFun->finalizeDataset(a, v, e, &np); + +} + + + + + + + + + + + + + + + + + +void postProcessing::startThread(int delflag) { + + /////////////////////////////////// Initialize dataset + + //resetDataQueue(); + + setTotalProgress(); + + initDataset(1); + + /////////////////////////////////// Start thread //////////////////////////////////////////////////////// +#ifdef VERBOSE + cout << "start thread stuff" << endl; +#endif + + pthread_attr_t tattr; + int ret; + sched_param param, mparam; + int policy= SCHED_OTHER; + + // set the priority; others are unchanged + //newprio = 30; + mparam.sched_priority =1; + param.sched_priority =1; + + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&tattr); + pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); + + + + // param.sched_priority = 5; + // scheduling parameters of main thread + ret = pthread_setschedparam(pthread_self(), policy, &mparam); + + //#ifdef VERBOSE + // printf("current priority is %d\n",param.sched_priority); + //#endif + if (delflag) + ret = pthread_create(&dataProcessingThread, &tattr,startProcessData, (void*)this); + else + ret = pthread_create(&dataProcessingThread, &tattr,startProcessDataNoDelete, (void*)this); + + pthread_attr_destroy(&tattr); + + // scheduling parameters of target thread + ret = pthread_setschedparam(dataProcessingThread, policy, ¶m); + +} + + + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.h new file mode 100644 index 000000000..90f00085a --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing.h @@ -0,0 +1,377 @@ +#ifndef POSTPROCESSING_H +#define POSTPROCESSING_H + + +#include "detectorData.h" +#include "slsDetectorBase.h" +#include "angularConversion.h" +#include "badChannelCorrections.h" +#include "fileIO.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class postProcessingFuncs; + + + +using namespace std; + +#define MAX_BADCHANS 20000 + + +#define defaultTDead {170,90,750} /**< should be changed in order to have it separate for the different detector types */ + + +/** + @short methods for data postprocessing + + (including thread for writing data files and plotting in parallel with the acquisition) +*/ + +class postProcessing : public angularConversion, public fileIO, public badChannelCorrections { + +//public virtual angularConversion, public virtual fileIO { + + public: + postProcessing(); + virtual ~postProcessing(); + + + + + /** + get bad channels correction + \param bad pointer to array that if bad!=NULL will be filled with the bad channel list + \returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + virtual int getBadChannelCorrection(int *bad=NULL)=0; + + + /** + get flat field corrections + \param corr if !=NULL will be filled with the correction coefficients + \param ecorr if !=NULL will be filled with the correction coefficients errors + \returns 0 if ff correction disabled, >0 otherwise + */ + virtual int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL)=0; + + /** + set flat field corrections + \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) + \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) + \returns 0 if ff correction disabled, >0 otherwise + */ + virtual int setFlatFieldCorrection(double *corr, double *ecorr=NULL)=0; + + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(string fname="")=0; + + + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \param nbad reference to number of bad channels + \param badlist array of badchannels + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(string fname, int &nbad, int *badlist, int off=0)=0; + using badChannelCorrections::setBadChannelCorrection; + + /** + set bad channels correction + \param nch number of bad channels + \param chs array of channels + \param ff 0 if normal bad channels, 1 if ff bad channels + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(int nch, int *chs, int ff=0)=0; + + + + int enableWriteToFileMask(int i=-1) {if (i>0) ((*correctionMask)|=(1<>WRITE_FILE) ;}; + + int enableOverwriteMask(int i=-1) {if (i>0) ((*correctionMask)|=(1<>OVERWRITE_FILE) ;}; + + int setAngularCorrectionMask(int i=-1){if (i==0) (*correctionMask)&=~(1<< ANGULAR_CONVERSION); if (i>0) (*correctionMask)|=(1<< ANGULAR_CONVERSION); return (((*correctionMask)&(1<< ANGULAR_CONVERSION))>>ANGULAR_CONVERSION);}; + + + + int enableAngularConversion(int i=-1) {if (i>0) return setAngularConversionFile("default"); if (i==0) return setAngularConversionFile(""); return setAngularCorrectionMask();}; + + + int enableBadChannelCorrection(int i=-1) {if (i>0) return setBadChannelCorrection("default"); if (i==0) return setBadChannelCorrection(""); return (((*correctionMask)&(1<< DISCARD_BAD_CHANNELS))>>DISCARD_BAD_CHANNELS);}; + + + + + /** returns the bad channel list file */ + string getBadChannelCorrectionFile() {if ((*correctionMask)&(1<< DISCARD_BAD_CHANNELS)) return string(badChanFile); else return string("none");}; + + + /** + get flat field corrections file directory + \returns flat field correction file directory + */ + string getFlatFieldCorrectionDir(){return string(flatFieldDir);}; + /** + set flat field corrections file directory + \param flat field correction file directory + \returns flat field correction file directory + */ + string setFlatFieldCorrectionDir(string dir){strcpy(flatFieldDir,dir.c_str()); return string(flatFieldDir);}; + + /** + get flat field corrections file name + \returns flat field correction file name + */ + string getFlatFieldCorrectionFile(){ if ((*correctionMask)&(1<=0) *threadedProcessing=b; return *threadedProcessing;}; + + + + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void *processData(int delflag); + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void processFrame(int* myData, int delflag, int jctb=0); + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void doProcessing(double* myData, int delflag, string fname); + + + /** + pops the data from the data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa dataQueue + */ + int* popDataQueue(); + + int* dataQueueFront(); + + int dataQueueSize(); + +/* /\** */ +/* pops the data from thepostprocessed data queue */ +/* \returns pointer to the popped data or NULL if the queue is empty. */ +/* \sa finalDataQueue */ +/* *\/ */ +/* detectorData* popFinalDataQueue(); */ + + + int checkJoinThread(); + void setJoinThread(int v); + + + /** + resets the raw data queue + \sa dataQueue + */ + void resetDataQueue(); + +/* /\** */ +/* resets the postprocessed data queue */ +/* \sa finalDataQueue */ +/* *\/ */ +/* void resetFinalDataQueue(); */ + + + + + + int fillBadChannelMask(); + + + + + virtual int rateCorrect(double*, double*, double*, double*)=0; + virtual int flatFieldCorrect(double*, double*, double*, double*)=0; + + + virtual int fillModuleMask(int *mM)=0; + + virtual int getNMods()=0; + + + + int GetCurrentPositionIndex(){ pthread_mutex_lock(&mp); int retval=getCurrentPositionIndex(); pthread_mutex_unlock(&mp); return retval;}; + void IncrementPositionIndex(){ pthread_mutex_lock(&mp); incrementPositionIndex(); pthread_mutex_unlock(&mp);}; + + void IncrementFileIndex(){ pthread_mutex_lock(&mp); incrementFileIndex(); pthread_mutex_unlock(&mp); }; + int GetFileIndex(){ pthread_mutex_lock(&mp); int i=*fileIndex; pthread_mutex_unlock(&mp); return i;}; + + void ResetPositionIndex(){pthread_mutex_lock(&mp); resetPositionIndex(); pthread_mutex_unlock(&mp);}; + + + void registerDataCallback(int( *userCallback)(detectorData*, int, int, void*), void *pArg) {dataReady = userCallback; pCallbackArg = pArg;}; + + + void registerRawDataCallback(int( *userCallback)(double*, int, void*), void *pArg) {rawDataReady = userCallback; pRawDataArg = pArg;}; + + virtual double getRateCorrectionTau()=0; + + + int positionFinished(int v=-1){pthread_mutex_lock(&mp); if (v>=0) posfinished=v; int retval=posfinished; pthread_mutex_unlock(&mp); return retval;}; + + double getCurrentPosition() {double p; pthread_mutex_lock(&mp); p=currentPosition; pthread_mutex_unlock(&mp); return p;}; + double setCurrentPosition(double v) { pthread_mutex_lock(&mp); currentPosition=v; pthread_mutex_unlock(&mp); return currentPosition;}; + + + + + void initDataset(int refresh); + void addFrame(double *data, double pos, double i0, double t, string fname, double var); + void finalizeDataset(double *a, double *v, double *e, int &np); + + virtual detectorType getDetectorsType(int pos=-1)=0; + + protected: + + int *threadedProcessing; + + int *correctionMask; + + char *flatFieldDir; + char *flatFieldFile; + + int64_t *expTime; + + /** mutex to synchronize main and data processing threads */ + pthread_mutex_t mp; + + + /** mutex to synchronizedata processing and plotting threads */ + pthread_mutex_t mg; + + /** mutex to synchronize slsdetector threads */ + pthread_mutex_t ms; + + /** sets when the acquisition is finished */ + int jointhread; + + /** sets when the position is finished */ + int posfinished; + + /** + data queue + */ + queue dataQueue; + /** + queue containing the postprocessed data + */ + queue finalDataQueue; + + + /** data queue size */ + int queuesize; + + /** queue mutex */ + sem_t sem_queue; + + /** set when detector finishes acquiring */ + int acquiringDone; + + + /** + start data processing thread + */ + void startThread(int delflag=1); // + /** the data processing thread */ + + pthread_t dataProcessingThread; + + + + /** pointer to bad channel mask 0 is channel is good 1 if it is bad \sa fillBadChannelMask() */ + int *badChannelMask; + + + + + /** + I0 measured + */ + double currentI0; + + + int arraySize; + + + + private: + double *fdata; + + int (*dataReady)(detectorData*,int, int,void*); + void *pCallbackArg; + + int (*rawDataReady)(double*,int,void*); + void *pRawDataArg; + + + postProcessingFuncs *ppFun; + detectorData *thisData; + + + double *ang; + double *val; + double *err; + + int numberOfChannels; + + + +}; + + +/* static void* startProcessData(void *n){\ */ +/* postProcessing *myDet=(postProcessing*)n;\ */ +/* myDet->processData(1);\ */ +/* pthread_exit(NULL);\ */ + +/* }; */ + +/* static void* startProcessDataNoDelete(void *n){\ */ +/* postProcessing *myDet=(postProcessing*)n;\ */ +/* myDet->processData(0);\ */ +/* pthread_exit(NULL);\ */ + +/* }; */ + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.cpp b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.cpp new file mode 100644 index 000000000..275003a6c --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.cpp @@ -0,0 +1,602 @@ +#include "postProcessingFileIO_Standalone.h" +#include "usersFunctions.h" +//#include "externPostProcessing.h" + +postProcessing::postProcessing(){ + + pthread_mutex_t mp1 = PTHREAD_MUTEX_INITIALIZER; + mp=mp1; + pthread_mutex_init(&mp, NULL); + mg=mp1; + pthread_mutex_init(&mg, NULL); + //cout << "reg callback "<< endl; + dataReady = 0; + pCallbackArg = 0; + registerDataCallback(&defaultDataReadyFunc, NULL); + //cout << "done "<< endl; + angConv=new angularConversion(numberOfPositions,detPositions,binSize, fineOffset, globalOffset); + IOfile= new fileIO(); + + //registerCallBackGetChansPerMod(&getChannelPerMod,this); + registerCallBackGetNumberofChannel(&defaultGetTotalNumberofChannels,this); + //registerAngularConversionCallback(&defaultAngularConversion,this); +} + + + + + + +int postProcessing::flatFieldCorrect(double datain, double errin, double &dataout, double &errout, double ffcoefficient, double fferr){ + double e; + + dataout=datain*ffcoefficient; + + if (errin==0 && datain>=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=sqrt(e*ffcoefficient*e*ffcoefficient+datain*fferr*datain*fferr); + else + errout=1.0; + + return 0; +}; + + + int postProcessing::rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t){ + + // double data; + double e; + + dataout=(datain*exp(tau*datain/t)); + + if (errin==0 && datain>=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=e*dataout*sqrt((1/(datain*datain)+tau*tau/(t*t))); + else + errout=1.; + return 0; + +}; + + + + + +int postProcessing::setBadChannelCorrection(ifstream &infile, int &nbad, int *badlist, int moff){ + + int interrupt=0; + int ich; + int chmin,chmax; + string str; + + + + nbad=0; + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + std::cout << str << std::endl; +#endif + istringstream ssstr; + ssstr.str(str); + if (ssstr.bad() || ssstr.fail() || infile.eof()) { + interrupt=1; + break; + } + if (str.find('-')!=string::npos) { + ssstr >> chmin ; + ssstr.str(str.substr(str.find('-')+1,str.size())); + ssstr >> chmax; +#ifdef VERBOSE + std::cout << "channels between"<< chmin << " and " << chmax << std::endl; +#endif + for (ich=chmin; ich<=chmax; ich++) { + if (nbad> ich; +#ifdef VERBOSE + std::cout << "channel "<< ich << std::endl; +#endif + if (nbadcreateFileName(getActionMask(),getCurrentScanVariable(0),getScanPrecision(0),getCurrentScanVariable(1),getScanPrecision(1),getCurrentPositionIndex(),getNumberOfPositions()); + +//Checking for write flag + if(*correctionMask&(1<writeDataFile (fname+string(".raw"),fdata, NULL, NULL, 'i'); + + } + + doProcessing(fdata,delflag, fname); + + delete [] myData; + myData=NULL; + fdata=NULL; + +#ifdef VERBOSE + cout << "Pop data queue " << *fileIndex << endl; +#endif + + pthread_mutex_lock(&mp); + dataQueue.pop(); //remove the data from the queue + queuesize=dataQueue.size(); + pthread_mutex_unlock(&mp); + + +} + + + + +void postProcessing::doProcessing(double *lfdata, int delflag, string fname) { + + +// /** write raw data file */ +// if (*correctionMask==0 && delflag==1) { +// // delete [] fdata; +// ; +// } else { + + + + double *rcdata=NULL, *rcerr=NULL; + double *ffcdata=NULL, *ffcerr=NULL; + double *ang=NULL; + // int imod; + int np; + //string fname; + detectorData *thisData; + + + string ext=".dat"; + // fname=createFileName(); + + /** rate correction */ + if (*correctionMask&(1<writeDataFile (fname+ext, ffcdata, ffcerr,ang);} + } + + if (*correctionMask&(1<< ANGULAR_CONVERSION) && getNumberOfPositions()>0) { +#ifdef VERBOSE + cout << "**************Current position index is " << getCurrentPositionIndex() << endl; +#endif + // if (*numberOfPositions>0) {setTotalNumberOfChannels + if (getCurrentPositionIndex()<=1) { + +#ifdef VERBOSE + cout << "reset merging " << endl; +#endif + angConv->resetMerging(); + } + +#ifdef VERBOSE + cout << "add to merging "<< getCurrentPositionIndex() << endl; +#endif + + angConv->addToMerging(ang, ffcdata, ffcerr, badChannelMask ); + +#ifdef VERBOSE + cout << getCurrentPositionIndex() << " " << getNumberOfPositions() << endl; + +#endif + + + // cout << "lock 1" << endl; + pthread_mutex_lock(&mp); + if ((getCurrentPositionIndex()>=getNumberOfPositions() && posfinished==1 && queuesize==1)) { + +#ifdef VERBOSE + cout << "finalize merging " << getCurrentPositionIndex()<< endl; +#endif + np=angConv->finalizeMerging(); + /** file writing */ + angConv->incrementPositionIndex(); + // cout << "unlock 1" << endl; + pthread_mutex_unlock(&mp); + + + fname=IOfile->createFileName(getActionMask(),getCurrentScanVariable(0),getScanPrecision(0),getCurrentScanVariable(1),getScanPrecision(1),getCurrentPositionIndex(),getNumberOfPositions()); + +#ifdef VERBOSE + cout << "writing merged data file" << endl; +#endif + if(*correctionMask&(1<writeDataFile (fname+ext,np,angConv->getMergedCounts(), angConv->getMergedErrors(), angConv->getMergedPositions(),'f');} +#ifdef VERBOSE + cout << " done" << endl; +#endif + + + +// if (delflag) { +// deleteMerging(); +// } else { + thisData=new detectorData(angConv->getMergedCounts(),angConv->getMergedErrors(),angConv->getMergedPositions(),getCurrentProgress(),(fname+ext).c_str(),np); + + // // cout << "lock 2" << endl; +// pthread_mutex_lock(&mg); +// finalDataQueue.push(thisData); +// // cout << "unlock 2" << endl; + +// pthread_mutex_unlock(&mg); + + if (dataReady) { + + dataReady(thisData, pCallbackArg); + delete thisData; + } + +// } + // cout << "lock 3" << endl; + pthread_mutex_lock(&mp); + } + // cout << "unlock 3" << endl; + pthread_mutex_unlock(&mp); + + if (ffcdata) + delete [] ffcdata; + + ffcdata=NULL; + + if (ffcerr) + delete [] ffcerr; + ffcerr=NULL; + + if (ang) + delete [] ang; + ang=NULL; + + } else { +// if (delflag) { +// if (ffcdata) +// delete [] ffcdata; +// if (ffcerr) +// delete [] ffcerr; +// if ( ang) +// delete [] ang; +// } else { + thisData=new detectorData(ffcdata,ffcerr,NULL,getCurrentProgress(),(fname+ext).c_str(),getTotalNumberOfChannels()); + + + if (dataReady) { + dataReady(thisData, pCallbackArg); + delete thisData; + } +// pthread_mutex_lock(&mg); +// finalDataQueue.push(thisData); + + +// pthread_mutex_unlock(&mg); +// } + } + //} + + if(*correctionMask&(1<incrementFileIndex();} +#ifdef VERBOSE + cout << "fdata is " << fdata << endl; +#endif + +} + + + + + +int postProcessing::fillBadChannelMask() { + + int nbad=0; + + if (*correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + nbad=getBadChannelCorrection(); +#ifdef VERBOSE + cout << "number of bad channels is " << nbad << endl; +#endif + if (nbad>0) { + + int *badChansList=new int[nbad]; + getBadChannelCorrection(badChansList); + + if (badChannelMask) + delete [] badChannelMask; + badChannelMask=new int[getTotalNumberOfChannels()]; + +#ifdef VERBOSE + cout << " pointer to bad channel mask is " << badChannelMask << endl; +#endif + for (int ichan=0; ichan=0 ) { + if (badChannelMask[badChansList[ichan]]==0) + nbad++; + badChannelMask[badChansList[ichan]]=1; + + } + } + delete [] badChansList; + + } else { + if (badChannelMask) { +#ifdef VERBOSE + cout << "deleting bad channel mask beacuse number of bad channels is 0" << endl; +#endif + + delete [] badChannelMask; + badChannelMask=NULL; + } + } + + } else { +#ifdef VERBOSE + cout << "bad channel correction is disabled " << nbad << endl; +#endif + if (badChannelMask) { +#ifdef VERBOSE + cout << "deleting bad channel mask beacuse no bad channel correction is selected" << endl; +#endif + delete [] badChannelMask; + badChannelMask=NULL; + } + } + +#ifdef VERBOSE + cout << "number of bad channels is " << nbad << endl; +#endif + return nbad; + +} + + + + + + +void* postProcessing::processData(int delflag) { + + +#ifdef VERBOSE + std::cout<< " processing data - threaded mode " << *threadedProcessing << endl; +#endif + + + angConv->setTotalNumberOfChannels(getTotalNumberOfChannels()); + IOfile->setTotalNumberofChannels(getTotalNumberOfChannels()); + setTotalProgress(); + pthread_mutex_lock(&mp); + queuesize=dataQueue.size(); + pthread_mutex_unlock(&mp); + + int *myData; + int dum=1; + + fdata=NULL; + + + while(dum | *threadedProcessing) { // ???????????????????????? + + + /* IF THERE ARE DATA PROCESS THEM*/ + pthread_mutex_lock(&mp); + while((queuesize=dataQueue.size())>0) { + /** Pop data queue */ + myData=dataQueue.front(); // get the data from the queue + pthread_mutex_unlock(&mp); + + if (myData) { + processFrame(myData,delflag); + //usleep(1000); + } + pthread_mutex_lock(&mp); + + } + pthread_mutex_unlock(&mp); + + /* IF THERE ARE NO DATA look if acquisition is finished */ + pthread_mutex_lock(&mp); + if (jointhread) { + if (dataQueue.size()==0) { + pthread_mutex_unlock(&mp); + break; + } + pthread_mutex_unlock(&mp); + } else { + pthread_mutex_unlock(&mp); + } + dum=0; + } + + if (fdata) { +#ifdef VERBOSE + cout << "delete fdata" << endl; +#endif + delete [] fdata; +#ifdef VERBOSE + cout << "done " << endl; +#endif + } + return 0; +} + + +int* postProcessing::popDataQueue() { + int *retval=NULL; + if( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + } + return retval; +} + +detectorData* postProcessing::popFinalDataQueue() { + detectorData *retval=NULL; + pthread_mutex_unlock(&mg); + if( !finalDataQueue.empty() ) { + retval=finalDataQueue.front(); + finalDataQueue.pop(); + } + pthread_mutex_unlock(&mg); + return retval; +} + +void postProcessing::resetDataQueue() { + int *retval=NULL; + while( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + delete [] retval; + } + +} + +void postProcessing::resetFinalDataQueue() { + detectorData *retval=NULL; + pthread_mutex_lock(&mg); + while( !finalDataQueue.empty() ) { + retval=finalDataQueue.front(); + finalDataQueue.pop(); + delete retval; + } + pthread_mutex_unlock(&mg); +} + + +void postProcessing::startThread(int delflag) { + pthread_attr_t tattr; + int ret; + sched_param param, mparam; + int policy= SCHED_OTHER; + + + // set the priority; others are unchanged + //newprio = 30; + mparam.sched_priority =1; + param.sched_priority =1; + + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&tattr); + pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); + + + + // param.sched_priority = 5; + // scheduling parameters of main thread + ret = pthread_setschedparam(pthread_self(), policy, &mparam); + //#ifdef VERBOSE + // printf("current priority is %d\n",param.sched_priority); + //#endif + if (delflag) + ret = pthread_create(&dataProcessingThread, &tattr,startProcessData, (void*)this); + else + ret = pthread_create(&dataProcessingThread, &tattr,startProcessDataNoDelete, (void*)this); + + pthread_attr_destroy(&tattr); + // scheduling parameters of target thread + ret = pthread_setschedparam(dataProcessingThread, policy, ¶m); + +} + + + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.h new file mode 100644 index 000000000..51e19a7df --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFileIO_Standalone.h @@ -0,0 +1,391 @@ +#ifndef POSTPROCESSING_H +#define POSTPROCESSING_H + + +#include "detectorData.h" +#include "sls_detector_defs.h" +#include "slsDetectorBase_Standalone.h" +#include "slsDetectorUsers.h" +#include "FileIO_Standalone.h" +#include "AngularConversion_Standalone.h" +//#include "externPostProcessing.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +class angularConversion; +class fileIO; + +using namespace std; + +#define MAX_BADCHANS 2000 + + +#define defaultTDead {170,90,750} /**< should be changed in order to have it separate for the different detector types */ + + +/** + @short methods for data postprocessing + + (including thread for writing data files and plotting in parallel with the acquisition) +*/ + +class postProcessing : public virtual slsDetectorBase1 { + + +//: public angularConversion, public fileIO + + public: + postProcessing(); + virtual ~postProcessing(){}; + + + + /** + get bad channels correction + \param bad pointer to array that if bad!=NULL will be filled with the bad channel list + \returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + virtual int getBadChannelCorrection(int *bad=NULL)=0; + + + /** + get flat field corrections + \param corr if !=NULL will be filled with the correction coefficients + \param ecorr if !=NULL will be filled with the correction coefficients errors + \returns 0 if ff correction disabled, >0 otherwise + */ + virtual int getFlatFieldCorrection(double *corr=NULL, double *ecorr=NULL)=0; + + /** + set flat field corrections + \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) + \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) + \returns 0 if ff correction disabled, >0 otherwise + */ + virtual int setFlatFieldCorrection(double *corr, double *ecorr=NULL)=0; + + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(string fname="")=0; + + static int setBadChannelCorrection(ifstream &infile, int &nbad, int *badlist, int moff=0); + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \param nbad reference to number of bad channels + \param badlist array of badchannels + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(string fname, int &nbad, int *badlist, int off=0)=0; + + + /** + set bad channels correction + \param nch number of bad channels + \param chs array of channels + \param ff 0 if normal bad channels, 1 if ff bad channels + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(int nch, int *chs, int ff=0)=0; + + /** + flat field correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param ffcoefficient flat field correction coefficient + \param fferr erro on ffcoefficient + \returns 0 + */ + static int flatFieldCorrect(double datain, double errin, double &dataout, double &errout, double ffcoefficient, double fferr); + + /** + rate correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param tau dead time 9in ns) + \param t acquisition time (in ns) + \returns 0 + */ + static int rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t); + + + int enableWriteToFile(int i=-1) {if (i>0) ((*correctionMask)|=(1<0) (*correctionMask)|=(1<< ANGULAR_CONVERSION); return ((*correctionMask)&(1<< ANGULAR_CONVERSION));}; + + + + int enableAngularConversion(int i=-1) {if (i>0) return setAngularConversionFile("default"); if (i==0) return setAngularConversionFile(""); return setAngularCorrectionMask();}; + + + int enableBadChannelCorrection(int i=-1) {if (i>0) return setBadChannelCorrection("default"); if (i==0) return setBadChannelCorrection(""); return ((*correctionMask)&(1<< DISCARD_BAD_CHANNELS));}; + + + + + /** returns the bad channel list file */ + string getBadChannelCorrectionFile() {if ((*correctionMask)&(1<< DISCARD_BAD_CHANNELS)) return string(badChanFile); else return string("none");}; + + + /** + get flat field corrections file directory + \returns flat field correction file directory + */ + string getFlatFieldCorrectionDir(){return string(flatFieldDir);}; + /** + set flat field corrections file directory + \param flat field correction file directory + \returns flat field correction file directory + */ + string setFlatFieldCorrectionDir(string dir){strcpy(flatFieldDir,dir.c_str()); return string(flatFieldDir);}; + + /** + get flat field corrections file name + \returns flat field correction file name + */ + string getFlatFieldCorrectionFile(){ if ((*correctionMask)&(1<=0) *threadedProcessing=b; return *threadedProcessing;}; + + + + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void *processData(int delflag); + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void processFrame(int* myData, int delflag); + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void doProcessing(double* myData, int delflag, string fname); + + + /** + pops the data from the data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa dataQueue + */ + int* popDataQueue(); + + /** + pops the data from thepostprocessed data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa finalDataQueue + */ + detectorData* popFinalDataQueue(); + + + /** + resets the raw data queue + \sa dataQueue + */ + void resetDataQueue(); + + /** + resets the postprocessed data queue + \sa finalDataQueue + */ + void resetFinalDataQueue(); + + + + + + int fillBadChannelMask(); + + + + + virtual int rateCorrect(double*, double*, double*, double*)=0; + virtual int flatFieldCorrect(double*, double*, double*, double*)=0; + + + + + + //void registerAngularConversionCallback(int (*sAngularConversion)(int & ,angleConversionConstant* ,void *), void *arg){seAngularConversion=sAngularConversion; pAngular= arg; }; + + void registerDataCallback(int( *userCallback)(detectorData*, void*), void *pArg) {dataReady = userCallback; pCallbackArg = pArg;}; + + void registerCallBackGetNumberofChannel(int (*func)(int, void *),void *arg){ getNoChannel=func;pNumberofChannel=arg;}; + + + + /** + sets the angular conversion file + \param fname file to read + \returns angular conversion flag + */ + + int setAngularConversionFile(string fname); + + //static int defaultAngularConversion(int &direc, angleConversionConstant *angoff,void *p=NULL){ return ((postProcessing *)p)->getAngularConversion( direc,angleConversionConstant *angoff=NULL);}; + /** + returns the angular conversion file + */ + string getAngularConversionFile(){if (setAngularCorrectionMask()) return string(angConvFile); else return string("none");}; + + //static int setAngularConversion(); + + static int defaultGetTotalNumberofChannels (int nChannel, void *p=NULL){ if(nChannel>=0){ return ((postProcessing*)p)->getTotalNumberOfChannels();} else return -1;}; + + protected: + + int *threadedProcessing; + + int *correctionMask; + + char *flatFieldDir; + char *flatFieldFile; + + char *badChanFile; + int *nBadChans; + int *badChansList; + int *nBadFF; + int *badFFList; + int *direction; + + /** pointer to angular conversion file name*/ + char *angConvFile; + + + /** mutex to synchronize main and data processing threads */ + pthread_mutex_t mp; + + + /** mutex to synchronizedata processing and plotting threads */ + pthread_mutex_t mg; + + /** sets when the acquisition is finished */ + int jointhread; + + /** sets when the position is finished */ + int posfinished; + + /** + data queue + */ + queue dataQueue; + /** + queue containing the postprocessed data + */ + queue finalDataQueue; + + + /** data queue size */ + int queuesize; + + + + + /** + start data processing thread + */ + void startThread(int delflag=1); // + /** the data processing thread */ + + pthread_t dataProcessingThread; + + + + /** pointer to bad channel mask 0 is channel is good 1 if it is bad \sa fillBadChannelMask() */ + int *badChannelMask; + + + + + /** + I0 measured + */ + double currentI0; + + double *fdata; + + int (*seAngularConversion)(int & ,angleConversionConstant* ,void*); + int (*getNoChannel)(int ,void*); + int (*dataReady)(detectorData*,void*); + void *pCallbackArg, *pChpermod,*pNumberofChannel,*pAngular; + + + + private: + + angularConversion *angConv; + fileIO *IOfile; + + /** pointer to beamlien fine offset*/ + double *fineOffset; + /** pointer to beamlien global offset*/ + double *globalOffset; + /** pointer to number of positions for the acquisition*/ + int *numberOfPositions; + + /** pointer to the detector positions for the acquisition*/ + double *detPositions; + + angleConversionConstant angcc[MAXMODS*MAXDET]; + + + /** pointer to angular bin size*/ + double *binSize; + + +}; + + +static void* startProcessData(void *n){\ + postProcessing *myDet=(postProcessing*)n;\ + myDet->processData(1);\ + pthread_exit(NULL);\ + +}; + +static void* startProcessDataNoDelete(void *n){\ + postProcessing *myDet=(postProcessing*)n;\ + myDet->processData(0);\ + pthread_exit(NULL);\ + +}; + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.cpp b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.cpp new file mode 100644 index 000000000..03b290a8e --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.cpp @@ -0,0 +1,561 @@ +#include "postProcessingFuncs.h" +#include "angleConversionConstant.h" + +//#define VERBOSE + +postProcessingFuncs::postProcessingFuncs(int *nModules,int *chPerMod,int modMask[],int badCh[], double ffcoeff[], double fferr[], double* t, int *dir, double angRadius[], double angOffset[], double angCentre[], double* to, double* bs, double *sX, double *sY): + nMods(0), chansPerMod(NULL), moduleMask(NULL), badChannelMask(NULL), ffCoeff(NULL), ffErr(NULL), tDead(0), angDir(1), angConv(NULL), totalOffset(0), binSize(0), sampleX(0), sampleY(0), totalChans(0), nBins(0), mp(NULL), mv(NULL), me(NULL), mm(NULL) +{ + initDataset(nModules, chPerMod,modMask,badCh, ffcoeff, fferr, t, dir, angRadius, angOffset, angCentre, to, bs, sX, sY); + +} + +int postProcessingFuncs::initDataset() { + + // cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA init dataset " << endl; + + if (nBins) { + mp=new double[nBins]; + mv=new double[nBins]; + me=new double[nBins]; + mm=new int[nBins]; + resetMerging(mp,mv,me,mm, nBins); + // cout << "nbins " << nBins << endl; + } else { + mv=new double[totalChans]; + me=new double[totalChans]; + // cout << "nchans " << totalChans << endl; + } + totalI0=0; + + return 0; + +} + +int postProcessingFuncs::finalizeDataset(double *ang, double *val, double *err, int *np) { + + // cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA finalize dataset " << endl; + + if (nBins) + *np=finalizeMerging(mp,mv,me,mm,nBins); + else + *np=totalChans; + + + + if (totalI0<=0) + totalI0=1.; + + + for (int ip=0; ip<(*np); ip++) { + + if (ang) + if (mp) + ang[ip]=mp[ip]; + + if (mv) + val[ip]=mv[ip]*totalI0; + + if (me) + err[ip]=me[ip]*totalI0; + + } + + + // cout << "delete mp " <0) { + i0=*I0; + totalI0+=i0; + } else + i0=-1; + +// if (badChannelMask) +// cout << "---------------- Discarding bad chans " << endl; + + // cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA add frame " << i0 << endl; + + for (int ich=0; ichchlast) { + // cout << *pos << " " << moduleMask[imod] << endl; + imod++; + ch0=chlast+1; + nchmod=chansPerMod[imod]; + chlast=ch0+nchmod-1; + } + + vin=data[ich]; + ein=0; + vout=data[ich]; + if (vout>=0) + eout=sqrt(vout); + else + eout=0; + + + if (tDead) { + //#ifdef VERBOSE + // cout << "ppFuncs ratecorrect" << endl; + //#endif + rateCorrect(vin, ein, vout, eout, tDead, *expTime); + vin=vout; + ein=eout; + } + //ffcorrect + + if (ffCoeff) { + //#ifdef VERBOSE + // cout << "ppFuncs ffcorrect" << endl; + //#endif + if (ffErr) + e=ffErr[ich]; + else + e=0; + flatFieldCorrect(vin, ein, vout, eout, ffCoeff[ich], e); + } + + + //i0correct + if (i0>0) { + //#ifdef VERBOSE + // cout << "ppFuncs i0 norm" << endl; + //#endif + vout/=i0; + eout/=i0; + } + + if (badChannelMask) { + //#ifdef VERBOSE + // cout << "ppFuncs badchans" << endl; + //#endif + if (badChannelMask[ich]) { + // cout << "------------------ Discarding channel " << ich << endl; + continue; + } + } + if (nBins) { + //angconv + +// #ifdef VERBOSE +// cout << "ppFuncs angconv" << endl; +// #endif +// //check module mask?!?!?!? + + + p1=convertAngle(*pos,ich-ch0,angConv[imod],moduleMask[imod],totalOffset,0,angDir); + +// #ifdef VERBOSE +// cout << "************************** ppFuncs merge" << endl; +// #endif + addPointToMerging(p1,vout,eout,mp,mv,me,mm, binSize, nBins); + + + } else { +#ifdef VERBOSE + cout << "ppFuncs merge" << endl; +#endif + //mp[ich]=ich; + mv[ich]+=vout; + me[ich]+=eout*eout; + } + } + return 0; +} + + + + + +int postProcessingFuncs::initDataset(int *nModules,int *chPerMod,int modMask[],int badCh[], double ffcoeff[], double fferr[], double* t, int *dir, double angRadius[], double angOffset[], double angCenter[], double* to, double* bs, double *sX, double *sY) { + + // cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA init dataset XXXXXX " << endl; + //#ifdef VERBOSE + // cout << "delete pointers " << endl; + //#endif + + deletePointers(); + + + //#ifdef VERBOSE + // cout << "nmod " << endl; + //#endif + + if (nModules) + nMods=*nModules; + else + nMods=0; + + + //#ifdef VERBOSE + //cout << nMods << endl; + //#endif +#ifdef VERBOSE + cout << "tdead " << endl; +#endif + + if (t) + tDead=*t; + else + tDead=0; + +#ifdef VERBOSE + cout << tDead << endl; +#endif +#ifdef VERBOSE + cout << "toffset " << endl; +#endif + + if (to) + totalOffset=*to; + else + totalOffset=0; +#ifdef VERBOSE + cout << totalOffset << endl; +#endif + + + //#ifdef VERBOSE + // cout << "binsize " << endl; + //#endif + if (bs) + binSize=*bs; + else + binSize=0; + + + //#ifdef VERBOSE + // cout << binSize << endl; + //#endif +#ifdef VERBOSE + cout << "samplex " << endl; +#endif + if (sX) + sampleX=*sX; + else + sampleX=0; + +#ifdef VERBOSE + cout << sampleX << endl; +#endif +#ifdef VERBOSE + cout << "sampley " << endl; +#endif + if (sY) + sampleY=*sY; + else + sampleY=0; + +#ifdef VERBOSE + cout << sampleY << endl; +#endif + //#ifdef VERBOSE + // cout << "angdir " << endl; + //#endif + if (dir) + angDir=*dir; + else + angDir=1; + + //#ifdef VERBOSE + // cout << angDir << endl; + //#endif + totalChans=0; + + + + chansPerMod=new int [nMods]; + + + moduleMask=new int [nMods]; + + nBins=0; + if (angRadius && angOffset && angCenter && (binSize>0)) { + // cout << "??????? creating angConv"<< endl; + angConv=new angleConversionConstant*[nMods]; + nBins=(int)(360./binSize)+1; + } + //#ifdef VERBOSE + //cout << "nBins " << nBins << endl; + //#endif + for (int im=0; im=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=sqrt(e*ffcoefficient*e*ffcoefficient+datain*fferr*datain*fferr); + else + errout=1.0; + + return 0; +}; + + + int postProcessingFuncs::rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t){ + + // double data; + double e; + + dataout=(datain*exp(tau*datain/t)); + + if (errin==0 && datain>=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=e*dataout*sqrt((1/(datain*datain)+tau*tau/(t*t))); + else + errout=1.; + return 0; + +}; + + +int postProcessingFuncs::calculateFlatField(int* nModules, int *chPerMod, int *moduleMask, int *badChannelMask, double *ffData, double *ffCoeff, double *ffErr) { + int nmed=0, im=0; + double *xmed; + + // cout << "Claculate flat field " << endl; + + if (chPerMod==NULL) + return -1; + // if (moduleMask==NULL) + // return -1; + if (ffData==NULL) + return -1; + + if (ffErr==NULL) + return -1; + + + // cout << *nModules << " pp chpm0 " << chPerMod[0] << endl; + int totch=0; + int nm= *nModules; + for (int im=0; im0) { + im=0; + while ((imim; i--) + xmed[i]=xmed[i-1]; + + xmed[im]=ffData[ich]; + nmed++; + + } + + + + } + + + if (nmed>1 && xmed[nmed/2]>0) { + //#ifdef VERBOSE + // std::cout<< "Flat field median is " << xmed[nmed/2] << " calculated using "<< nmed << " points" << std::endl; + //#endif + + + // cout << "checking bad channel mask " << endl; + for (int ich=0; ich0) { + ffCoeff[ich]=xmed[nmed/2]/ffData[ich]; + ffErr[ich]=ffCoeff[ich]*sqrt(ffData[ich])/ffData[ich]; + } else { + ffCoeff[ich]=0.; + ffErr[ich]=1.; + } + cout << ich << " " << ffData[ich] << " " << ffCoeff[ich] << endl; + } + + } + cout << "done " << endl; + + delete [] xmed; + xmed=NULL; + + return 0; + +} + + + + + + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.h new file mode 100644 index 000000000..daf779e87 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessingFuncs.h @@ -0,0 +1,80 @@ +#ifndef POSTPROCESSINGFUNCS_H +#define POSTPROCESSINGFUNC_H + + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "angularConversionStatic.h" +class angleConversionConstant; + +using namespace std; + + +class postProcessingFuncs : public virtual angularConversionStatic + +{ + + public: + postProcessingFuncs(int *nModules=NULL,int *chPerMod=NULL,int *modMask=NULL,int *badChMask=NULL, double *ffcoeff=NULL, double *fferr=NULL, double* t=NULL, int *dir=NULL, double *angRadius=NULL, double *angOffset=NULL, double *angCentre=NULL, double* to=NULL, double* bs=NULL, double *sX=NULL, double *sY=NULL); + + + ~postProcessingFuncs(); + + + int initDataset(int *nModules,int *chPerMod,int modMask[],int badCh[], double ffcoeff[], double fferr[], double* tDead, int *dir, double angRadius[], double angOffset[], double angCentre[], double* to, double* bs, double *sX, double *sY); + + int initDataset(); + + + int finalizeDataset(double ang[], double val[], double err[], int *np); + + int addFrame(double data[], double *pos, double *IO, double *expTime, const char *filename, double *var=0); + + static int calculateFlatField(int* nModules, int *chPerMod, int moduleMask[], int badChannelMask[], double ffData[], double ffCoeff[], double ffErr[]); + + static int flatFieldCorrect(double datain, double errin, double &dataout, double &errout, double ffcoefficient, double fferr); + + + static int rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t); + + private: + void deletePointers(); + + + int nMods; + int *chansPerMod; + int *moduleMask; + int *badChannelMask; + double *ffCoeff; + double *ffErr; + double tDead; + int angDir; + angleConversionConstant **angConv; + double totalOffset; + double binSize; + double sampleX; + double sampleY; + int totalChans; + + int nBins; + + double totalI0; + + + double *mp, *mv,*me; + int *mm; + +}; + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.cpp b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.cpp new file mode 100644 index 000000000..185d811ad --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.cpp @@ -0,0 +1,593 @@ +#include "postProcessing.h" +#include "usersFunctions.h" +//#include "angularConversion.h" + +//#include "AngularConversion_Standalone.h" + +postProcessing::postProcessing(){ + pthread_mutex_t mp1 = PTHREAD_MUTEX_INITIALIZER; + mp=mp1; + pthread_mutex_init(&mp, NULL); + mg=mp1; + pthread_mutex_init(&mg, NULL); + //cout << "reg callback "<< endl; + dataReady = 0; + pCallbackArg = 0; + registerDataCallback(&defaultDataReadyFunc, NULL); + //tregisterCallBackGetChansPerMod(&defaultGetChansPerMod,NULL); + //cout << "done "<< endl; + angConv=new angularConversion(numberOfPositions,detPositions,binSize, fineOffset, globalOffset); +} + + + + + + +int postProcessing::flatFieldCorrect(double datain, double errin, double &dataout, double &errout, double ffcoefficient, double fferr){ + double e; + + dataout=datain*ffcoefficient; + + if (errin==0 && datain>=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=sqrt(e*ffcoefficient*e*ffcoefficient+datain*fferr*datain*fferr); + else + errout=1.0; + + return 0; +}; + + + int postProcessing::rateCorrect(double datain, double errin, double &dataout, double &errout, double tau, double t){ + + // double data; + double e; + + dataout=(datain*exp(tau*datain/t)); + + if (errin==0 && datain>=0) + e=sqrt(datain); + else + e=errin; + + if (dataout>0) + errout=e*dataout*sqrt((1/(datain*datain)+tau*tau/(t*t))); + else + errout=1.; + return 0; + +}; + + + + + +int postProcessing::setBadChannelCorrection(ifstream &infile, int &nbad, int *badlist, int moff){ + + int interrupt=0; + int ich; + int chmin,chmax; + string str; + + + + nbad=0; + while (infile.good() and interrupt==0) { + getline(infile,str); +#ifdef VERBOSE + std::cout << str << std::endl; +#endif + istringstream ssstr; + ssstr.str(str); + if (ssstr.bad() || ssstr.fail() || infile.eof()) { + interrupt=1; + break; + } + if (str.find('-')!=string::npos) { + ssstr >> chmin ; + ssstr.str(str.substr(str.find('-')+1,str.size())); + ssstr >> chmax; +#ifdef VERBOSE + std::cout << "channels between"<< chmin << " and " << chmax << std::endl; +#endif + for (ich=chmin; ich<=chmax; ich++) { + if (nbad> ich; +#ifdef VERBOSE + std::cout << "channel "<< ich << std::endl; +#endif + if (nbad0) { +#ifdef VERBOSE + cout << "**************Current position index is " << getCurrentPositionIndex() << endl; +#endif + // if (*numberOfPositions>0) { + if (getCurrentPositionIndex()<=1) { + +#ifdef VERBOSE + cout << "reset merging " << endl; +#endif + angConv->resetMerging(); + } + +#ifdef VERBOSE + cout << "add to merging "<< getCurrentPositionIndex() << endl; +#endif + + angConv->addToMerging(ang, ffcdata, ffcerr, badChannelMask ); + +#ifdef VERBOSE + cout << getCurrentPositionIndex() << " " << getNumberOfPositions() << endl; + +#endif + + + // cout << "lock 1" << endl; + pthread_mutex_lock(&mp); + if ((getCurrentPositionIndex()>=getNumberOfPositions() && posfinished==1 && queuesize==1)) { + +#ifdef VERBOSE + cout << "finalize merging " << getCurrentPositionIndex()<< endl; +#endif + np=angConv->finalizeMerging(); + /** file writing */ + angConv->incrementPositionIndex(); + // cout << "unlock 1" << endl; + pthread_mutex_unlock(&mp); + + + fname=createFileName(); + +#ifdef VERBOSE + cout << "writing merged data file" << endl; +#endif + writeDataFile (fname+ext,np,angConv->getMergedCounts(), angConv->getMergedErrors(), angConv->getMergedPositions(),'f'); +#ifdef VERBOSE + cout << " done" << endl; +#endif + + + +// if (delflag) { +// deleteMerging(); +// } else { + thisData=new detectorData(angConv->getMergedCounts(),angConv->getMergedErrors(),angConv->getMergedPositions(),getCurrentProgress(),(fname+ext).c_str(),np); + + // // cout << "lock 2" << endl; +// pthread_mutex_lock(&mg); +// finalDataQueue.push(thisData); +// // cout << "unlock 2" << endl; + +// pthread_mutex_unlock(&mg); + + if (dataReady) { + + dataReady(thisData, pCallbackArg); + delete thisData; + } + +// } + // cout << "lock 3" << endl; + pthread_mutex_lock(&mp); + } + // cout << "unlock 3" << endl; + pthread_mutex_unlock(&mp); + + if (ffcdata) + delete [] ffcdata; + + ffcdata=NULL; + + if (ffcerr) + delete [] ffcerr; + ffcerr=NULL; + + if (ang) + delete [] ang; + ang=NULL; + + } else { +// if (delflag) { +// if (ffcdata) +// delete [] ffcdata; +// if (ffcerr) +// delete [] ffcerr; +// if ( ang) +// delete [] ang; +// } else { + thisData=new detectorData(ffcdata,ffcerr,NULL,getCurrentProgress(),(fname+ext).c_str(),getTotalNumberOfChannels()); + + + if (dataReady) { + dataReady(thisData, pCallbackArg); + delete thisData; + } +// pthread_mutex_lock(&mg); +// finalDataQueue.push(thisData); + + +// pthread_mutex_unlock(&mg); +// } + } + //} + + incrementFileIndex(); +#ifdef VERBOSE + cout << "fdata is " << fdata << endl; +#endif + +} + + + + + +int postProcessing::fillBadChannelMask() { + + int nbad=0; + + if (*correctionMask&(1<< DISCARD_BAD_CHANNELS)) { + nbad=getBadChannelCorrection(); +#ifdef VERBOSE + cout << "number of bad channels is " << nbad << endl; +#endif + if (nbad>0) { + + int *badChansList=new int[nbad]; + getBadChannelCorrection(badChansList); + + if (badChannelMask) + delete [] badChannelMask; + badChannelMask=new int[getTotalNumberOfChannels()]; + +#ifdef VERBOSE + cout << " pointer to bad channel mask is " << badChannelMask << endl; +#endif + for (int ichan=0; ichan=0 ) { + if (badChannelMask[badChansList[ichan]]==0) + nbad++; + badChannelMask[badChansList[ichan]]=1; + + } + } + delete [] badChansList; + + } else { + if (badChannelMask) { +#ifdef VERBOSE + cout << "deleting bad channel mask beacuse number of bad channels is 0" << endl; +#endif + + delete [] badChannelMask; + badChannelMask=NULL; + } + } + + } else { +#ifdef VERBOSE + cout << "bad channel correction is disabled " << nbad << endl; +#endif + if (badChannelMask) { +#ifdef VERBOSE + cout << "deleting bad channel mask beacuse no bad channel correction is selected" << endl; +#endif + delete [] badChannelMask; + badChannelMask=NULL; + } + } + +#ifdef VERBOSE + cout << "number of bad channels is " << nbad << endl; +#endif + return nbad; + +} + + + + + + +void* postProcessing::processData(int delflag) { + + +#ifdef VERBOSE + std::cout<< " processing data - threaded mode " << *threadedProcessing << endl; +#endif + + + angConv->setTotalNumberOfChannels(getTotalNumberOfChannels()); + setTotalProgress(); + pthread_mutex_lock(&mp); + queuesize=dataQueue.size(); + pthread_mutex_unlock(&mp); + + int *myData; + int dum=1; + + fdata=NULL; + + + while(dum | *threadedProcessing) { // ???????????????????????? + + + /* IF THERE ARE DATA PROCESS THEM*/ + pthread_mutex_lock(&mp); + while((queuesize=dataQueue.size())>0) { + /** Pop data queue */ + myData=dataQueue.front(); // get the data from the queue + pthread_mutex_unlock(&mp); + + if (myData) { + processFrame(myData,delflag); + //usleep(1000); + } + pthread_mutex_lock(&mp); + + } + pthread_mutex_unlock(&mp); + + /* IF THERE ARE NO DATA look if acquisition is finished */ + pthread_mutex_lock(&mp); + if (jointhread) { + if (dataQueue.size()==0) { + pthread_mutex_unlock(&mp); + break; + } + pthread_mutex_unlock(&mp); + } else { + pthread_mutex_unlock(&mp); + } + dum=0; + } + + if (fdata) { +#ifdef VERBOSE + cout << "delete fdata" << endl; +#endif + delete [] fdata; +#ifdef VERBOSE + cout << "done " << endl; +#endif + } + return 0; +} + + +int* postProcessing::popDataQueue() { + int *retval=NULL; + if( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + } + return retval; +} + +detectorData* postProcessing::popFinalDataQueue() { + detectorData *retval=NULL; + pthread_mutex_unlock(&mg); + if( !finalDataQueue.empty() ) { + retval=finalDataQueue.front(); + finalDataQueue.pop(); + } + pthread_mutex_unlock(&mg); + return retval; +} + +void postProcessing::resetDataQueue() { + int *retval=NULL; + while( !dataQueue.empty() ) { + retval=dataQueue.front(); + dataQueue.pop(); + delete [] retval; + } + +} + +void postProcessing::resetFinalDataQueue() { + detectorData *retval=NULL; + pthread_mutex_lock(&mg); + while( !finalDataQueue.empty() ) { + retval=finalDataQueue.front(); + finalDataQueue.pop(); + delete retval; + } + pthread_mutex_unlock(&mg); +} + + +void postProcessing::startThread(int delflag) { + pthread_attr_t tattr; + int ret; + sched_param param, mparam; + int policy= SCHED_OTHER; + + + // set the priority; others are unchanged + //newprio = 30; + mparam.sched_priority =1; + param.sched_priority =1; + + + /* Initialize and set thread detached attribute */ + pthread_attr_init(&tattr); + pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE); + + + + // param.sched_priority = 5; + // scheduling parameters of main thread + ret = pthread_setschedparam(pthread_self(), policy, &mparam); + //#ifdef VERBOSE + // printf("current priority is %d\n",param.sched_priority); + //#endif + if (delflag) + ret = pthread_create(&dataProcessingThread, &tattr,startProcessData, (void*)this); + else + ret = pthread_create(&dataProcessingThread, &tattr,startProcessDataNoDelete, (void*)this); + + pthread_attr_destroy(&tattr); + // scheduling parameters of target thread + ret = pthread_setschedparam(dataProcessingThread, policy, ¶m); + +} + + + diff --git a/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.h b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.h new file mode 100644 index 000000000..2006553d4 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/postProcessing_Standalone.h @@ -0,0 +1,367 @@ +#ifndef POSTPROCESSING_H +#define POSTPROCESSING_H + + +#include "detectorData.h" +#include "fileIO.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +class angularConversion; + +using namespace std; + +#define MAX_BADCHANS 2000 + + +#define defaultTDead {170,90,750} /**< should be changed in order to have it separate for the different detector types */ + + +/** + @short methods for data postprocessing + + (including thread for writing data files and plotting in parallel with the acquisition) +*/ + +class postProcessing : public virtual fileIO { + + +//: public angularConversion, public fileIO + + public: + postProcessing(); + virtual ~postProcessing(){}; + + + + + /** + get bad channels correction + \param bad pointer to array that if bad!=NULL will be filled with the bad channel list + \returns 0 if bad channel disabled or no bad channels, >0 otherwise + */ + virtual int getBadChannelCorrection(int *bad=NULL)=0; + + + /** + get flat field corrections + \param corr if !=NULL will be filled with the correction coefficients + \param ecorr if !=NULL will be filled with the correction coefficients errors + \returns 0 if ff correction disabled, >0 otherwise + */ + virtual int getFlatFieldCorrection(float *corr=NULL, float *ecorr=NULL)=0; + + /** + set flat field corrections + \param corr if !=NULL the flat field corrections will be filled with corr (NULL usets ff corrections) + \param ecorr if !=NULL the flat field correction errors will be filled with ecorr (1 otherwise) + \returns 0 if ff correction disabled, >0 otherwise + */ + virtual int setFlatFieldCorrection(float *corr, float *ecorr=NULL)=0; + + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(string fname="")=0; + + static int setBadChannelCorrection(ifstream &infile, int &nbad, int *badlist, int moff=0); + /** + set bad channels correction + \param fname file with bad channel list ("" disable) + +ff + \param nbad reference to number of bad channels + \param badlist array of badchannels + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(string fname, int &nbad, int *badlist, int off=0)=0; + + + /** + set bad channels correction + \param nch number of bad channels + \param chs array of channels + \param ff 0 if normal bad channels, 1 if ff bad channels + \returns 0 if bad channel disabled, >0 otherwise + */ + virtual int setBadChannelCorrection(int nch, int *chs, int ff=0)=0; + + /** + flat field correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param ffcoefficient flat field correction coefficient + \param fferr erro on ffcoefficient + \returns 0 + */ + static int flatFieldCorrect(float datain, float errin, float &dataout, float &errout, float ffcoefficient, float fferr); + + /** + rate correct data + \param datain data + \param errin error on data (if<=0 will default to sqrt(datain) + \param dataout corrected data + \param errout error on corrected data + \param tau dead time 9in ns) + \param t acquisition time (in ns) + \returns 0 + */ + static int rateCorrect(float datain, float errin, float &dataout, float &errout, float tau, float t); + + + int enableWriteToFile(int i=-1) {if (i>0) ((*correctionMask)|=(1<0) (*correctionMask)|=(1<< ANGULAR_CONVERSION); return ((*correctionMask)&(1<< ANGULAR_CONVERSION));}; + + + + int enableAngularConversion(int i=-1) {if (i>0) return setAngularConversionFile("default"); if (i==0) return setAngularConversionFile(""); return setAngularCorrectionMask();}; + + + int enableBadChannelCorrection(int i=-1) {if (i>0) return setBadChannelCorrection("default"); if (i==0) return setBadChannelCorrection(""); return ((*correctionMask)&(1<< DISCARD_BAD_CHANNELS));}; + + + + + /** returns the bad channel list file */ + string getBadChannelCorrectionFile() {if ((*correctionMask)&(1<< DISCARD_BAD_CHANNELS)) return string(badChanFile); else return string("none");}; + + + /** + get flat field corrections file directory + \returns flat field correction file directory + */ + string getFlatFieldCorrectionDir(){return string(flatFieldDir);}; + /** + set flat field corrections file directory + \param flat field correction file directory + \returns flat field correction file directory + */ + string setFlatFieldCorrectionDir(string dir){strcpy(flatFieldDir,dir.c_str()); return string(flatFieldDir);}; + + /** + get flat field corrections file name + \returns flat field correction file name + */ + string getFlatFieldCorrectionFile(){ if ((*correctionMask)&(1<=0) *threadedProcessing=b; return *threadedProcessing;}; + + + + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void *processData(int delflag); + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void processFrame(int* myData, int delflag); + + /** processes the data + \param delflag 0 leaves the data in the final data queue + \returns nothing + + */ + void doProcessing(float* myData, int delflag, string fname); + + + /** + pops the data from the data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa dataQueue + */ + int* popDataQueue(); + + /** + pops the data from thepostprocessed data queue + \returns pointer to the popped data or NULL if the queue is empty. + \sa finalDataQueue + */ + detectorData* popFinalDataQueue(); + + + /** + resets the raw data queue + \sa dataQueue + */ + void resetDataQueue(); + + /** + resets the postprocessed data queue + \sa finalDataQueue + */ + void resetFinalDataQueue(); + + + + + + int fillBadChannelMask(); + + + + + virtual int rateCorrect(float*, float*, float*, float*)=0; + virtual int flatFieldCorrect(float*, float*, float*, float*)=0; + + + + + + + + void registerDataCallback(int( *userCallback)(detectorData*, void*), void *pArg) {dataReady = userCallback; pCallbackArg = pArg;}; + //void registerCallBackGetChansPerMod(int (*func)(int, void *),void *arg){ getChansPerMod=func;pChpermod=arg;} + + + + /** + sets the angular conversion file + \param fname file to read + \returns angular conversion flag + */ + + int setAngularConversionFile(string fname); + + + /** + returns the angular conversion file + */ + string getAngularConversionFile(){if (setAngularCorrectionMask()) return string(angConvFile); else return string("none");}; + + + + protected: + + int *threadedProcessing; + + int *correctionMask; + + char *flatFieldDir; + char *flatFieldFile; + + char *badChanFile; + int *nBadChans; + int *badChansList; + int *nBadFF; + int *badFFList; + + /** pointer to angular conversion file name*/ + char *angConvFile; + + + /** mutex to synchronize main and data processing threads */ + pthread_mutex_t mp; + + + /** mutex to synchronizedata processing and plotting threads */ + pthread_mutex_t mg; + + /** sets when the acquisition is finished */ + int jointhread; + + /** sets when the position is finished */ + int posfinished; + + /** + data queue + */ + queue dataQueue; + /** + queue containing the postprocessed data + */ + queue finalDataQueue; + + + /** data queue size */ + int queuesize; + + + + + /** + start data processing thread + */ + void startThread(int delflag=1); // + /** the data processing thread */ + + pthread_t dataProcessingThread; + + + + /** pointer to bad channel mask 0 is channel is good 1 if it is bad \sa fillBadChannelMask() */ + int *badChannelMask; + + + + + /** + I0 measured + */ + float currentI0; + + float *fdata; + + + //int (*getChansPerMod)(int, void*); + + + int (*dataReady)(detectorData*,void*); + void *pCallbackArg, *pChpermod; + + + + private: + angularConversion *angConv; + + +}; + + +static void* startProcessData(void *n){\ + postProcessing *myDet=(postProcessing*)n;\ + myDet->processData(1);\ + pthread_exit(NULL);\ + +}; + +static void* startProcessDataNoDelete(void *n){\ + postProcessing *myDet=(postProcessing*)n;\ + myDet->processData(0);\ + pthread_exit(NULL);\ + +}; + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/runningStat.h b/slsDetectorSoftware/slsDetectorAnalysis/runningStat.h new file mode 100644 index 000000000..98ab7986f --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/runningStat.h @@ -0,0 +1,92 @@ + /********************************************//** + * @file runningStat.h + * @short handles pedestal data and doesnt move + ***********************************************/ +#ifndef RUNNINGSTAT_H +#define RUNNINGSTAT_H + +#include + +//#include "sls_detector_defs.h" +#include +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; + +/** + @short class handling pedestal data that is static + */ + +class runningStat{ + +public: + /** + * Constructor + */ + runningStat() : m_n(0),m_oldM(0),m_newM(0),m_oldS(0),m_newS(0) {} + + /** + * Clear number of data values + */ + void Clear(){ + m_n = 0; + } + + /** + * Push Pedestal + */ + void Push(double x){ + m_n++; + + // See Knuth TAOCP vol 2, 3rd edition, page 232 + if (m_n == 1){ + m_oldM = m_newM = x; + m_oldS = 0.0; + }else{ + m_newM = m_oldM + (x - m_oldM)/m_n; + m_newS = m_oldS + (x - m_oldM)*(x - m_newM); + + // set up for next iteration + m_oldM = m_newM; + m_oldS = m_newS; + } + } + + /** + * Get number of data values + */ + int NumDataValues() const{ + return m_n; + } + + /** + * Get mean + */ + double Mean() const{ + return (m_n > 0) ? m_newM : 0.0; + } + + /** + * Get variance + */ + double Variance() const{ + return ( (m_n > 1) ? m_newS/(m_n - 1) : 0.0 ); + } + + /** + * Get standard deviation + */ + double StandardDeviation() const{ + return sqrt( Variance() ); + } + +private: + /** number of data values */ + int m_n; + + /** old and new mean */ + double m_oldM, m_newM, m_oldS, m_newS; + +}; + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/singlePhotonFilter.cpp b/slsDetectorSoftware/slsDetectorAnalysis/singlePhotonFilter.cpp new file mode 100644 index 000000000..8731f36dc --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/singlePhotonFilter.cpp @@ -0,0 +1,678 @@ + /********************************************//** + * @file singlePhotonFilter.cpp + * @short single photon filter using trees + ***********************************************/ +#include "singlePhotonFilter.h" +#include + + +#define BUF_SIZE (16*1024*1024) //16mb +#define HEADER_SIZE_NUM_FRAMES 2 +#define HEADER_SIZE_NUM_PACKETS 1 + + +singlePhotonFilter::singlePhotonFilter(int nx, int ny, + int fmask, int pmask, int foffset, int poffset, int pperf, int iValue, + int16_t *m, int16_t *s, CircularFifo* f, int d, int* tfcaught, int* fcaught,uint32_t* cframenum): +#ifdef MYROOT1 + myTree(NULL), +#else + + nHitsPerFile(0), + nTotalHits(0), +#endif + myFile(NULL), + nHitsPerFrame(0), + nChannelsX(nx), + nChannelsY(ny), + nClusterX(CLUSTER_SIZE), + nClusterY(CLUSTER_SIZE), + map(m), + dataSize(d), + mask(s), + nped(DEFAULT_NUM_PEDESTAL), + nsigma(DEFAULT_SIGMA), + nbackground(DEFAULT_BACKGROUND), + outcorr(DEFAULT_CORRECTION), + fnum(0), + pnum(0), + ptot(0), + f0(0), + frame_index_mask(fmask), + packet_index_mask(pmask), + frame_index_offset(foffset), + packet_index_offset(poffset), + packets_per_frame(pperf), + incrementValue(iValue), + firstTime(true), + ret(0), + pIndex(0), + fIndex(0), + thread_started(0), + threads_mask(0x0), + currentThread(-1), + thisThreadIndex(-1), + fileIndex(0), + fifo(f), + totalFramesCaught(tfcaught), + framesCaught(fcaught), + currentframenum(cframenum), + freeFifoCallBack(NULL), + pFreeFifo(NULL){ + //cluster + if (nChannelsX) + nClusterX = 1; + +#ifndef MYROOT1 + //photonHitList=(single_photon_hit**) (new int*[nChannelsX*nChannelsY/(nClusterX*nClusterY)*1000]); + photonHitList=new single_photon_hit*[nChannelsX*nChannelsY/(nClusterX*nClusterY)*1000]; + for (int ii=0; iidata = new double[nClusterX*nClusterY]; + myPhotonHit->x = 0; + myPhotonHit->y = 0; + myPhotonHit->rms = 0; + myPhotonHit->ped = 0; + myPhotonHit->iframe = -1; + + for(int i=0;i < NUM_THREADS; i++){ + /*smp[i] = NULL;*/ + mem0[i]=NULL; + } + numFramesAlloted = new int[NUM_THREADS]; + + strcpy(savefilename,""); + strcpy(filePath,""); + strcpy(fileName,"run"); + + pthread_mutex_init(&write_mutex,NULL); + pthread_mutex_init(&running_mutex,NULL); + pthread_mutex_init(&frnum_mutex,NULL); + + + +} + + +singlePhotonFilter::~singlePhotonFilter(){ + enableCompression(false); + if(numFramesAlloted) delete [] numFramesAlloted; + writeToFile(); + closeFile(); + if(myFile) delete myFile; + if(mask) delete mask; + if(stat) delete stat; + if(nHitStat) delete nHitStat; + /*if(smp) delete []smp;*/ + if(mem0) delete [] mem0; + if(fifo) delete fifo; +} + + + + + + +int singlePhotonFilter::enableCompression(bool enable){ +//#ifdef VERBOSE + cout << "Compression set to " << enable; +#ifdef MYROOT1 + cout << " with root" << endl; +#else + cout << " without root" << endl; +#endif +//#endif + if(enable){ + threads_mask = 0x0; + currentThread = -1; + + for(int i=0; ifindHits(); + return this_pointer; +} + + + +int singlePhotonFilter::initTree(){ +#ifdef MYROOT1 + writeToFile(); + closeFile(); + sprintf(savefilename, "%s/%s_%d_.root", filePath,fileName,fileIndex); + + //file + myFile = new TFile(savefilename, "RECREATE"); /** later return error if it exists */ + cout<<"File created: "<Branch("iframe",&myPhotonHit->iframe,"iframe/I"); + myTree->Branch("x",&myPhotonHit->x,"x/I"); + myTree->Branch("y",&myPhotonHit->y,"y/I"); + myTree->Branch("data",myPhotonHit->data,cdata); + myTree->Branch("pedestal",&myPhotonHit->ped,"pedestal/D"); + myTree->Branch("rms",&myPhotonHit->rms,"rms/D"); +#else + + writeToFile(); + closeFile(); + sprintf(savefilename, "%s/%s_f%012d_%d.raw", filePath,fileName,nTotalHits,fileIndex); + myFile = fopen(savefilename, "w"); + setvbuf(myFile,NULL,_IOFBF,BUF_SIZE); + cout<<"File created: "<Write(); + nHitsPerFrame = 0; + return OK; + }else + cout << "ERROR: Could not write to " << nHitsPerFrame << " hits to file as file or tree doesnt exist" << endl; +#else + if(myFile){ + int ii; + /*cout<<"writing "<< nHitsPerFrame << " hits to file" << endl;*/ + for (ii=0; iiwrite(myFile); + // delete photonHitList[ii]; + } + // delete photonHitList[ii]; + // photonHitList[0]=new single_photon_hit(nClusterX,nClusterY); + + // fwrite((void*)(photonHitList), 1, sizeof(single_photon_hit)*nHitsPerFrame, myFile); + /*framesInFile += nHitsPerFrame;*/ + nHitsPerFrame = 0; + //cout<<"Exiting writeToFile"<GetCurrentFile(); + myFile->Close(); + myFile = NULL;//delete myFile; + } + myTree = NULL;//delete myTree; + } +#else + if(myFile) + fclose(myFile); + myFile = NULL; +#endif + return OK; +} + + + + + +void singlePhotonFilter::setupAcquisitionParameters(char *outfpath, char* outfname, int outfIndex){ + fileIndex = outfIndex; + strcpy(filePath,outfpath); + strcpy(fileName,outfname); + + fnum = 0; pnum = 0; ptot = 0; f0 = 0; firstTime = true; currentThread = -1; + *framesCaught = 0; + *currentframenum = 0; + + //initialize + for (int ir=0; irClear(); + nHitStat->SetN(nbackground); +#ifndef MYROOT1 + nTotalHits = 0; +#endif +} + + +/* + rets +case 0: waiting for next packet of new frame +case 1: finished with full frame, + start new frame +case -1: last packet of current frame, + invalidate remaining packets, + start new frame +case -2: first packet of new frame, + invalidate remaining packets, + check buffer needs to be pushed, + start new frame with the current packet, + then ret = 0 +case -3: last packet of new frame, + invalidate remaining packets, + check buffer needs to be pushed, + start new frame with current packet, + then ret = -1 (invalidate remaining packets and start a new frame) + */ +int singlePhotonFilter::verifyFrame(char *inData){ + ret = 0; + pIndex = 0; + fIndex = 0; + fIndex = (((uint32_t)(*((uint32_t*)inData)))& frame_index_mask) >> frame_index_offset; + pIndex = (((uint32_t)(*((uint32_t*)inData)))& packet_index_mask) >> packet_index_offset; + + //check validity of packet index + if ((pIndex < 0) && (pIndex >= packets_per_frame)){ + cout << "cannot decode packet index:" << pIndex << endl; + //its already dealt with cuz this frame will be discarded in the end + } + pIndex += incrementValue; + + //for moench, put first packet last + if (pIndex == 0) + pIndex = packets_per_frame; +//#ifdef VERYVERBOSE + cout<<"fi:"<>frame_index_offset); + //progress + if((clusteriframe + PROGRESS_INCREMENT) > *currentframenum){ + pthread_mutex_lock(&frnum_mutex); + *currentframenum = clusteriframe; + pthread_mutex_unlock(&frnum_mutex); + /*cout<<"currentframenum:"<data; + + //for each pixel + for (ir=0; ir= (dataSize))){ + cout << "Bad Channel Mapping index: " << map[currentIndex] << endl; + continue; + } + + //if frame within pedestal number + if (clusteriframe < nped){ + stat[currentIndex].Calc((double)(mask[currentIndex] ^ myData[map[currentIndex]])); + // frame outside pedestal number + }else{ + + dum = 1; + tot = 0; + clusterrms = stat[currentIndex].StandardDeviation();//-1 + clusterped = stat[currentIndex].Mean();//0 + sigmarms = clusterrms * nsigma; + + + clusterData[clusterCenterPixel] = ((double)(mask[currentIndex] ^ myData[map[currentIndex]])) - clusterped; + for (r=-deltaX; r <= deltaX; ++r ){ + if (((ir+r) < 0) || ((ir+r) >= nChannelsX)) + continue; + for(c=-1; c <= 1; ++c){ + if (((ic+c) < 0) || ((ic+c) >= nChannelsY)) + continue; + + + pixelIndex = currentIndex + (r*nChannelsY+c); + + if ((map[pixelIndex] < 0) || (map[pixelIndex] >= dataSize)){ + cout << "Bad Channel Mapping index: " << map[pixelIndex] << endl; + continue; + } + + clusterIndex = pixelIndex-(currentIndex - deltaX * nChannelsY - 1); + clusterData[clusterIndex] = ((double)(mask[pixelIndex] ^ myData[map[pixelIndex]])) - stat[pixelIndex].Mean(); + tot += clusterData[clusterIndex]; + //discard negative events + if (clusterData[clusterIndex] > clusterData[clusterCenterPixel]) + dum = 2; + + } + + } + + + if (tot < sqrtCluster * sigmarms) + dum = 0; + //discard events (for pedestal) where sum of the neighbours is too large. + if (clusterData[clusterCenterPixel] < sigmarms && dum != 0) + dum = 3; + //Appriximated running average + if (clusterData[clusterCenterPixel] > -sigmarms && + clusterData[clusterCenterPixel] < sigmarms && + dum == 0){ + stat[currentIndex].Calc((double)(mask[currentIndex]^myData[map[currentIndex]])); + } + // this is an event and we are in the center + else if (dum == 1){ + pthread_mutex_lock(&write_mutex); +#ifdef MYROOT1 + myTree->Fill(); +#else + for (int ix=0; ixdata[ix] = clusterData[ix]; + + photonHitList[nHitsPerFrame]->x = ic; + photonHitList[nHitsPerFrame]->y = ir; + photonHitList[nHitsPerFrame]->rms = clusterrms; + photonHitList[nHitsPerFrame]->ped = clusterped; + photonHitList[nHitsPerFrame]->iframe = clusteriframe; + //hit.write(myFile); + + nHitsPerFrame++; + + // cout << nHitsPerFrame << " " << nChannelsX*nChannelsY/(nClusterX*nClusterY)*1000 << endl; + + // photonHitList[nHitsPerFrame]=new single_photon_hit(nClusterX,nClusterY); + // cout << "done" << endl; + nHitsPerFile++; + nTotalHits++; + if(nHitsPerFile >= MAX_HITS_PER_FILE-1) + initTree(); +#endif + pthread_mutex_unlock(&write_mutex); + } + + } + } + } + }else{ + //cout<< "did no receiver fulll frame"<Calc((double)nHitsPerFrame); + //write for each frame, not packet + + pthread_mutex_lock(&write_mutex); + cout << "write to file " << nHitsPerFrame << endl; + writeToFile(); + pthread_mutex_unlock(&write_mutex); + + //increment offset + isData += dataSize; + + /* + if ((clusteriframe%1000 == 0) && (clusteriframe != 0) ){ + cout << dec << "Frame: " << clusteriframe << " Hit Avg over last frames: " << + nHitStat->Mean() << " .. "<StandardDeviation() << endl; + cout<<"writing "<< nHitsPerFrame << " hits to file" << endl; + } + */ + } + + pthread_mutex_lock(&write_mutex); + if(freeFifoCallBack) + freeFifoCallBack(freeData,pFreeFifo); + //fifo->push(freeData);//fifo->push(isData); + pthread_mutex_unlock(&write_mutex); + + //thread not running + pthread_mutex_lock(&running_mutex); + threads_mask^=(1<=25000) { + cout<<"*****************problem: "<<((theData-listmem0)/4096)<<" :"< +#include +#include +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "circularFifo.h" +#include "runningStat.h" +#include "movingStat.h" +#include "single_photon_hit.h" +using namespace std; + + +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; +#define MAX_STR_LENGTH 1000 + +/** + return values +*/ +enum { + OK, /**< function succeeded */ + FAIL /**< function failed */ +}; + + +/** + @short class handling trees and its data file + */ + +class singlePhotonFilter{ +public: + /** + * Constructor + * @param nx Number of Channels in X direction + * @param ny Number of Channels in Y direction + * @param fmask frame index mask + * @param pmask packet index mask + * @param foffset frame index offset + * @param poffset packet index offset + * @param pperf packets per frame + * @param iValue increment value (only for gotthard to increment index to have matching frame number) + * @param m Map to data without headers + * @param s mask as to which adcs are inverted + * @param f circular fifo buffer, which needs to be freed + * @param d Size of data with the headers + * @param tfcaught pointer to total frames caught- needs updation for client + * @param fcaught pointer to frames caught - needs updation for client + * @param cframenum pointer to currentframe num- needs updation for progress for gui + */ + singlePhotonFilter( + int nx, + int ny, + int fmask, + int pmask, + int foffset, + int poffset, + int pperf, + int iValue, + int16_t *m, + int16_t *s, + CircularFifo* f, + int d, + int* tfcaught, + int* fcaught, + uint32_t* cframenum); + + /** virtual destructor */ + virtual ~singlePhotonFilter(); + +#ifdef MYROOT1 + /** + * returns tree + */ + TTree *getTree(){ return myTree; }; +#endif + + /** + * Returns packets per frame + */ + int getPacketsPerFrame(){ return packets_per_frame;}; + + /** + * returns struct + */ + single_photon_hit* getStructure(){ return myPhotonHit; }; + + /** Set number of frames to calculate pedestal at beginning */ + void setNPed(int n){ nped = n; }; + + /** Get number of frames to calculate pedestal at beginning */ + int getNPed(){return nped;}; + + /** Set Distance from pedestal to detect a hit */ + void setNSigma(int n){ nsigma = n; }; + + /** Get Distance from pedestal to detect a hit */ + int getNSigma(){return nsigma;}; + + /** Set background */ + void setNBackground(int n){ nbackground = n; }; + + /** Get background */ + int getNBackground(){return nbackground;}; + + /** Set correction */ + void setOutCorr(double d){ outcorr = d; }; + + /** Get correction */ + double getOutCorr(){return outcorr;}; + + /** + * Construct a tree, populate struct for the single photon hit and provide all the masks and offsets + * @param outdir Output file directory/Output file name + * returns OK if successful, else FAIL + + */ + int initTree(); + + /** + * Writes tree/struct to file + * returns OK if successful, else FAIL + */ + int writeToFile(); + + /** + * Closes file + * returns OK if successful, else FAIL + */ + int closeFile(); + + /** + * Reset Indices before starting acquisition + */ + void setupAcquisitionParameters(char *outfpath, char* outfname, int outfIndex); + + /** reconstruct the frame with all the right packets + * @param inData the data from socket to be verified + * returns + * 0: waiting for next packet of new frame + * 1: finished with full frame, + * start new frame + * -1: last packet of current frame, + * invalidate remaining packets, + * start new frame + * -2: first packet of new frame, + * invalidate remaining packets, + * check buffer needs to be pushed, + * start new frame with the current packet, + * then ret = 0 + * -3: last packet of new frame, + * invalidate remaining packets, + * check buffer needs to be pushed, + * start new frame with current packet, + * then ret = -1 (invalidate remaining packets and start a new frame) + */ + int verifyFrame(char *inData); + + /** + * Find Hits frame by frame and save it in file/tree + */ + void findHits(); + + /** Enable or disable compression + * @param enable true to enable compression and false to disable + * returns OK for success or FAIL for failure, incase threads fail to start + * */ + int enableCompression(bool enable); + + /** create threads for compression + * @param this_pointer obejct of this class + * */ + static void* createThreads(void *this_pointer); + + /** assignjobs to each thread + * @param thisData a bunch of frames + * @param numThisData number of frames + * */ + void assignJobsForThread(char *thisData, int numThisData); + + /** Checks if all the threads are done processing + * @param returns 1 for jobs done and 0 for jobs not done + * */ + int checkIfJobsDone(); + + /** + * call back to free fifo + * call back arguments are + * fbuffer buffer address to be freed + */ + void registerCallBackFreeFifo(void (*func)(char*, void*),void *arg){freeFifoCallBack=func; pFreeFifo=arg;}; + + + +private: + +#ifdef MYROOT1 + /** Tree where the hits are stored */ + TTree *myTree; + + /** File where the tree is saved */ + TFile *myFile; +#else + FILE *myFile; + + /** pointer to array of structs when only using files */ + //single_photon_hit* photonHitList; + single_photon_hit ** photonHitList; + + /** Number of Hits per file */ + int nHitsPerFile; + + /** Total Number of Hits Per Acquisition */ + int nTotalHits; +#endif + + /** Number of Hits per frame*/ + int nHitsPerFrame; + + /** Maximum Number of hits written to file */ + const static int MAX_HITS_PER_FILE = 2000000; + + /** Number of Channels in X direction */ + int nChannelsX; + + /** Number of Channels in Y direction */ + int nChannelsY; + + /** Cluster size in X direction */ + int nClusterX; + + /** Cluster size in Y direction */ + int nClusterY; + + /** map to the data without headers */ + int16_t *map; + + /** Size of data with headers */ + int dataSize; + + /** mask as to which adcs are inverted */ + int16_t *mask; + + /** movingStat object */ + movingStat *stat; + + movingStat *nHitStat; + + /** single Photon Hit structure */ + single_photon_hit* myPhotonHit; + + /** Cluster size */ + const static int CLUSTER_SIZE = 3; + + /** Default Number of frames at the beginning to calculate pedestal */ + const static int DEFAULT_NUM_PEDESTAL = 500; + + /** Default Distance from pedestal to detect a hit */ + const static int DEFAULT_SIGMA = 5; + + /** Default Background */ + const static int DEFAULT_BACKGROUND = 1000; + + /** Default Correction Percentage */ + const static double DEFAULT_CORRECTION = 1.0; + + /** Number of frames at the beginning to calculate pedestal */ + int nped; + + /** Distance from pedestal to detect a hit */ + int nsigma; + + /** background */ + int nbackground; + + /** correction */ + double outcorr; + + /** previous frame index */ + unsigned int fnum; + + /** previous packet index */ + unsigned int pnum; + + /** total packets received */ + unsigned int ptot; + + /** first frame number */ + unsigned int f0; + + /** frame index mask */ + int frame_index_mask; + + /** packet index mask */ + int packet_index_mask; + + /** frame index offset */ + int frame_index_offset; + + /** packet index offset */ + int packet_index_offset; + + /** number of packets per frame */ + int packets_per_frame; + + /** increment value for index for gotthard */ + int incrementValue; + + /** first packet */ + bool firstTime; + + /** return status */ + int ret; + + /** current packet index */ + int pIndex; + + /** current frame index */ + int fIndex; + + /** thread related variables */ + static const int NUM_THREADS = 15; + pthread_t find_hits_thread[NUM_THREADS]; + volatile int thread_started; + volatile int threads_mask; + pthread_mutex_t write_mutex; + pthread_mutex_t running_mutex; + pthread_mutex_t frnum_mutex; + + static const int PROGRESS_INCREMENT = 100; + /** current thread the job being allotted to */ + int currentThread; + + /** current index alloted for each thread */ + int thisThreadIndex; + + /** semaphore to synchronize between different jobs on same thread */ + sem_t smp[NUM_THREADS]; + + /** starting memory of data for different threads */ + char* mem0[NUM_THREADS]; + + /** number of frames alloted for each thread to process */ + int* numFramesAlloted; + + + + /** final file name */ + char savefilename[MAX_STR_LENGTH]; + + /** file path */ + char filePath[MAX_STR_LENGTH]; + + /** file prefix */ + char fileName[MAX_STR_LENGTH]; + + /** file acquisition index */ + int fileIndex; + + + /** 0 for 1d and 1 for 2d */ + int deltaX; + + /** index of center of cluster for 1d and for 2d*/ + int clusterCenterPixel; + + /** squareroot of cluster */ + double sqrtCluster; + + /** circular fifo buffer to be freed */ + CircularFifo* fifo; + + /**total frames caught */ + int* totalFramesCaught; + + /** frames caught */ + int* framesCaught; + + /** current frame number */ + uint32_t* currentframenum; + + /** call back function */ + void (*freeFifoCallBack)(char*, void*); + + /** call back arguments */ + void *pFreeFifo; +}; + + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorAnalysis/single_photon_hit.h b/slsDetectorSoftware/slsDetectorAnalysis/single_photon_hit.h new file mode 100644 index 000000000..278c9f691 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorAnalysis/single_photon_hit.h @@ -0,0 +1,44 @@ +#ifndef SINGLE_PHOTON_HIT_H +#define SINGLE_PHOTON_HIT_h + +typedef double double32_t; +typedef float float32_t; +typedef int int32_t; + +/* /\** */ +/* @short structure for a single photon hit */ +/* *\/ */ +/* typedef struct{ */ +/* double* data; /\**< data size *\/ */ +/* int x; /\**< x-coordinate of the center of hit *\/ */ +/* int y; /\**< x-coordinate of the center of hit *\/ */ +/* double rms; /\**< noise of central pixel *\/ */ +/* double ped; /\**< pedestal of the central pixel *\/ */ +/* int iframe; /\**< frame number *\/ */ +/* }single_photon_hit; */ + + +class single_photon_hit { + + public: + single_photon_hit(int nx, int ny=1): dx(nx), dy(ny) {data=new double[dx*dy];}; + ~single_photon_hit(){delete [] data;}; + void write(FILE *myFile) {fwrite((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fwrite((void*)data, 1, dx*dy*sizeof(double), myFile);}; + void read(FILE *myFile) {fread((void*)this, 1, 3*sizeof(int)+2*sizeof(double), myFile); fread((void*)data, 1, dx*dy*sizeof(double), myFile);}; + void set_data(double v, int ix, int iy=0){data[(iy+dy/2)*dx+ix+dx/2]=v;}; + double get_data(int ix, int iy=0){return data[(iy+dy/2)*dx+ix+dx/2];}; + + + int x; /**< x-coordinate of the center of hit */ + int y; /**< x-coordinate of the center of hit */ + double rms; /**< noise of central pixel */ + double ped; /**< pedestal of the central pixel */ + int iframe; /**< frame number */ + double *data; /**< data size */ + const int dx; + const int dy; +}; + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorClient/Makefile b/slsDetectorSoftware/slsDetectorClient/Makefile new file mode 100644 index 000000000..fef04074a --- /dev/null +++ b/slsDetectorSoftware/slsDetectorClient/Makefile @@ -0,0 +1,112 @@ +CFLAGS= -DC_ONLY +#FLAGS=-DVERBOSE +#ASM=$(shell echo "/lib/modules/`uname -r`/build/include") + +#INCLUDES= -I../slsDetectorSoftware/commonFiles -I../slsDetectorSoftware/slsDetector -I ../slsDetectorSoftware/MySocketTCP -I../slsDetectorSoftware/usersFunctions -I../slsDetectorSoftware/multiSlsDetector -I../slsDetectorSoftware/slsDetectorAnalysis -I../slsDetectorSoftware/slsReceiverInterface -I$(ASM) +#LDFLAG= + + + +INCLUDES?= -I../commonFiles -I../slsDetector -I ../MySocketTCP -I../usersFunctions -I../multiSlsDetector -I../slsDetectorAnalysis -I../slsReceiverInterface -I$(shell echo "/lib/modules/`uname -r`/build/include") + + +LIBDIR?=../ +LIBS?= -L$(LIBDIR) -lSlsDetector + +LDFLAG= -L/usr/lib64/ -lpthread + + +DESTDIR ?= bin +DOCDIR ?= $(PWD)/docs + +BIN=$(DESTDIR) + +SRC_CLNT=sls_detector_client.cpp + +clients: $(DESTDIR)/sls_detector_put $(DESTDIR)/sls_detector_get $(DESTDIR)/sls_detector_acquire $(DESTDIR)/sls_detector_help + echo $(LIBS) + +static_clients: $(DESTDIR)/ssls_detector_put $(DESTDIR)/ssls_detector_get $(DESTDIR)/ssls_detector_acquire $(DESTDIR)/ssls_detector_help + +all: clients + echo $(LIBS) + +nonstatic: clients + + + +lib: + cd ../ && $(MAKE) DESTDIR=$(LIBDIR) + + + +$(DESTDIR)/ssls_detector_put: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -static -o $(BIN)/ssls_detector_put $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DPUT $(LIBS) $(LDFLAG) + +$(DESTDIR)/ssls_detector_get: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -static -o $(BIN)/ssls_detector_get $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DGET $(LIBS) $(LDFLAG) + +$(DESTDIR)/ssls_detector_acquire: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -static -o $(BIN)/ssls_detector_acquire $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DREADOUT $(LIBS) $(LDFLAG) + +$(DESTDIR)/ssls_detector_help: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -static -o $(BIN)/ssls_detector_help $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DHELP $(LIBS) $(LDFLAG) + + + +$(DESTDIR)/sls_detector_put: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_put $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DPUT $(LIBS) $(LDFLAG) + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + +$(DESTDIR)/sls_detector_get: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_get $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DGET $(LIBS) $(LDFLAG) + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + +$(DESTDIR)/sls_detector_acquire: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_acquire $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DREADOUT $(LIBS) $(LDFLAG) + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + +$(DESTDIR)/sls_detector_help: $(SRC_CLNT) lib + echo $(LIBS) + echo $(LDFLAG) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_help $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DHELP $(LIBS) $(LDFLAG) + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + + +doc: + cd manual && make DESTDIR=$(DOCDIR) + +htmldoc: + cd manual && make html DESTDIR=$(DOCDIR) + +clean: +# cd manual && make clean + rm -rf $(BIN)/sls_detector_put $(BIN)/sls_detector_get $(BIN)/sls_detector_acquire $(BIN)/sls_detector_help + +install: clients + + + + diff --git a/slsDetectorSoftware/slsDetectorClient/Makefile.x04sa b/slsDetectorSoftware/slsDetectorClient/Makefile.x04sa new file mode 100644 index 000000000..7e2daa9bd --- /dev/null +++ b/slsDetectorSoftware/slsDetectorClient/Makefile.x04sa @@ -0,0 +1,54 @@ +CFLAGS= -DC_ONLY +FLAGS=-DVERBOSE +INCLUDES= -I../slsDetectorSoftware/commonFiles -I../slsDetectorSoftware/slsDetector -I ../slsDetectorSoftware/MySocketTCP -I../slsDetectorSoftware/usersFunctions -I../slsDetectorSoftware/multiSlsDetector -I../slsDetectorSoftware/slsDetectorAnalysis +LIBS= -L../slsDetectorSoftware/ +LDFLAG= -lSlsDetector -lpthread + +EPICSFLAGS=-DEPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/SL5-x86/ -Wl,-R/usr/local/epics/base/lib/SL5-x86 -lca -lCom + +BIN=bin + +SRC_CLNT=sls_detector_client.cpp + +clients: sls_detector_put sls_detector_get sls_detector_acquire sls_detector_help + +all: lib clients + +lib: + cd ../slsDetectorSoftware && $(MAKE) lib + + + +sls_detector_put: $(SRC_CLNT) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_put $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DPUT $(LIBS) $(LDFLAG) $(EPICSFLAGS) + +sls_detector_get: $(SRC_CLNT) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_get $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DGET $(LIBS) $(LDFLAG) $(EPICSFLAGS) + +sls_detector_acquire: $(SRC_CLNT) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_acquire $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DREADOUT $(LIBS) $(LDFLAG) $(EPICSFLAGS) + +sls_detector_help: $(SRC_CLNT) + mkdir -p $(BIN) + $(CXX) -o $(BIN)/sls_detector_help $(SRC_CLNT) $(FLAGS) $(INCLUDES) -DHELP $(LIBS) $(LDFLAG) $(EPICSFLAGS) + + +clean: + rm -rf $(BIN)/sls_detector_* + + + + + +install_sls_detector: all + $(shell test -d $(DESTDIR) || mkdir -p $(DESTDIR)) + cp -P $(BIN)/sls_detector_put $(DESTDIR) + cp -P $(BIN)/sls_detector_get $(DESTDIR) + cp -P $(BIN)/sls_detector_acquire $(DESTDIR) + cp -P $(BIN)/sls_detector_help $(DESTDIR) + + + diff --git a/slsDetectorSoftware/slsDetectorClient/sls_detector_client.cpp b/slsDetectorSoftware/slsDetectorClient/sls_detector_client.cpp new file mode 100644 index 000000000..bed9b9848 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorClient/sls_detector_client.cpp @@ -0,0 +1,37 @@ +#include "multiSlsDetectorClient.h" + + +#include +using namespace std; + +int main(int argc, char *argv[]) + +{ +#ifdef PUT + int action=slsDetectorDefs::PUT_ACTION; +#endif + +#ifdef GET + int action=slsDetectorDefs::GET_ACTION; +#endif + + +#ifdef READOUT + int action=slsDetectorDefs::READOUT_ACTION; +#endif + + +#ifdef HELP + int action=slsDetectorDefs::HELP_ACTION; +#endif + + multiSlsDetectorClient *cl; + if (argc>1) + cl=new multiSlsDetectorClient(argc-1, argv+1, action); + else + cl=new multiSlsDetectorClient(argc-1, argv, action); + + delete cl; +} + + diff --git a/slsDetectorSoftware/slsDetectorServer/Makefile b/slsDetectorSoftware/slsDetectorServer/Makefile new file mode 100644 index 000000000..8c3ee8d97 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/Makefile @@ -0,0 +1,26 @@ +CC = gcc +CLAGS += -Wall -DVIRTUAL -DDACS_INT -DGENERICD # -DSLS_DETECTOR_FUNCTION_LIST +LDLIBS += -lm + +PROGS = genericDetectorServer +DESTDIR ?= bin +INSTMODE = 0777 + +SRC_CLNT = slsDetectorServer.c slsDetectorServer_funcs.c communication_funcs.c slsDetectorFunctionList.c +OBJS = $(SRC_CLNT:.cpp=.o) + + + +all: clean $(PROGS) + +boot: $(OBJS) + +$(PROGS): + echo $(OBJS) + mkdir -p $(DESTDIR) + $(CC) $(SRC_CLNT) $(CLAGS) $(LDLIBS) -o $@ + mv $(PROGS) $(DESTDIR) + + +clean: + rm -rf $(DESTDIR)/$(PROGS) *.o diff --git a/slsDetectorSoftware/slsDetectorServer/communication_funcs.c b/slsDetectorSoftware/slsDetectorServer/communication_funcs.c new file mode 120000 index 000000000..87a4f95d1 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/communication_funcs.c @@ -0,0 +1 @@ +../commonFiles/communication_funcs.c \ No newline at end of file diff --git a/slsDetectorSoftware/slsDetectorServer/communication_funcs.h b/slsDetectorSoftware/slsDetectorServer/communication_funcs.h new file mode 120000 index 000000000..f220903b2 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/communication_funcs.h @@ -0,0 +1 @@ +../commonFiles/communication_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.c b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.c new file mode 100644 index 000000000..c28ab462d --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.c @@ -0,0 +1,838 @@ +#ifdef SLS_DETECTOR_FUNCTION_LIST + +#include "slsDetectorFunctionList.h" +#include "slsDetectorServer_defs.h" + +#include +#include + + +const int nChans=NCHAN; +const int nChips=NCHIP; +const int nDacs=NDAC; +const int nAdcs=NADC; +const int allSelected=-2; +const int noneSelected=-1; + +sls_detector_module *detectorModules=NULL; +int *detectorChips=NULL; +int *detectorChans=NULL; +dacs_t *detectorDacs=NULL; +dacs_t *detectorAdcs=NULL; + +int nModY = NMAXMOD; +int nModX = NMAXMOD; +int dynamicRange= DYNAMIC_RANGE; +int dataBytes = NMAXMOD*NCHIP*NCHAN*2; +int masterMode = NO_MASTER; +int syncMode = NO_SYNCHRONIZATION; +int timingMode = AUTO_TIMING; + + + +enum detectorSettings thisSettings; +int sChan, sChip, sMod, sDac, sAdc; +int nModBoard; +extern int dataBytes; + + +int initializeDetectorStructure(){ + + int imod; + int n=getNModBoard(X)*getNModBoard(Y); +#ifdef VERBOSE + printf("Board is for %d modules\n",n); +#endif + detectorModules=malloc(n*sizeof(sls_detector_module)); + detectorChips=malloc(n*NCHIP*sizeof(int)); + detectorChans=malloc(n*NCHIP*NCHAN*sizeof(int)); + detectorDacs=malloc(n*NDAC*sizeof(int)); + detectorAdcs=malloc(n*NADC*sizeof(int)); +#ifdef VERBOSE + printf("modules from 0x%x to 0x%x\n",(unsigned int)(detectorModules), (unsigned int)(detectorModules+n)); + printf("chips from 0x%x to 0x%x\n",(unsigned int)(detectorChips), (unsigned int)(detectorChips+n*NCHIP)); + printf("chans from 0x%x to 0x%x\n",(unsigned int)(detectorChans), (unsigned int)(detectorChans+n*NCHIP*NCHAN)); + printf("dacs from 0x%x to 0x%x\n",(unsigned int)(detectorDacs), (unsigned int)(detectorDacs+n*NDAC)); + printf("adcs from 0x%x to 0x%x\n",(unsigned int)(detectorAdcs), (unsigned int)(detectorAdcs+n*NADC)); +#endif + for (imod=0; imoddacs=detectorDacs+imod*NDAC; + (detectorModules+imod)->adcs=detectorAdcs+imod*NADC; + (detectorModules+imod)->chipregs=detectorChips+imod*NCHIP; + (detectorModules+imod)->chanregs=detectorChans+imod*NCHIP*NCHAN; + (detectorModules+imod)->ndac=NDAC; + (detectorModules+imod)->nadc=NADC; + (detectorModules+imod)->nchip=NCHIP; + (detectorModules+imod)->nchan=NCHIP*NCHAN; + (detectorModules+imod)->module=imod; + (detectorModules+imod)->gain=0; + (detectorModules+imod)->offset=0; + (detectorModules+imod)->reg=0; + /* initialize registers, dacs, retrieve sn, adc values etc */ + } + thisSettings=UNINITIALIZED; + sChan=noneSelected; + sChip=noneSelected; + sMod=noneSelected; + sDac=noneSelected; + sAdc=noneSelected; + + return OK; +} + + + + + + +int setupDetector(){ + //testFpga(); + //testRAM(); + + //setSettings(GET_SETTINGS,-1); + //setFrames(1); + //setTrains(1); + //setExposureTime(1e6); + //setPeriod(1e9); + //setDelay(0); + //setGates(0); + + //setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + //setMaster(GET_MASTER); + //setSynchronization(GET_SYNCHRONIZATION_MODE); + return OK; +} + + + + +int setNMod(int nm, enum dimension dim){ + return 1; +} + + + +int getNModBoard(enum dimension arg){ + return 1; +} + + + + + + + + +int64_t getModuleId(enum idMode arg, int imod){ + //DETECTOR_SERIAL_NUMBER + //DETECTOR_FIRMWARE_VERSION + return 0; +} + + + + +int64_t getDetectorId(enum idMode arg){ + //DETECTOR_SOFTWARE_VERSION defined in slsDetector_defs.h? + return 0; +} + + + + + +int moduleTest( enum digitalTestMode arg, int imod){ + //template testShiftIn from mcb_funcs.c + + //CHIP_TEST + //testShiftIn + //testShiftOut + //testShiftStSel + //testDataInOutMux + //testExtPulseMux + //testOutMux + //testFpgaMux + + return OK; +} + + + + + +int detectorTest( enum digitalTestMode arg){ + //templates from firmware_funcs.c + + //DETECTOR_FIRMWARE_TEST:testFpga() + //DETECTOR_MEMORY_TEST:testRAM() + //DETECTOR_BUS_TEST:testBus() + //DETECTOR_SOFTWARE_TEST:testFpga() + return OK; +} + + + + + + +double setDAC(enum dacIndex ind, double val, int imod){ + //template initDACbyIndexDACU from mcb_funcs.c + + //check that slsDetectorServer_funcs.c set_dac() has all the specific dac enums + //set dac and write to a register in fpga to remember dac value when server restarts + return 0; +} + + + +double getADC(enum dacIndex ind, int imod){ + //get adc value + return 0; +} + + + + +int setChannel(sls_detector_channel myChan){ + //template initChannelByNumber() from mcb_funcs.c + + return myChan.reg; +} + + +int getChannel(sls_detector_channel *myChan){ + //template getChannelbyNumber() from mcb_funcs.c + return FAIL; +} + + + +int setChip(sls_detector_chip myChip){ + //template initChipbyNumber() from mcb_funcs.c + return myChip.reg; +} + + +int getChip(sls_detector_chip *myChip){ + //template getChipbyNumber() from mcb_funcs.c + return FAIL; +} + +int setModule(sls_detector_module myChan){ + //template initModulebyNumber() from mcb_funcs.c + return OK; +} + +int getModule(sls_detector_module *myChan){ + //template getModulebyNumber() from mcb_funcs.c + return FAIL; +} + +int getThresholdEnergy(int imod){ + //template getThresholdEnergy() from mcb_funcs.c + //depending on settings + return FAIL; +} + + +int setThresholdEnergy(int thr, int imod){ + //template getThresholdEnergy() from mcb_funcs.c + //depending on settings + return FAIL; +} + + + +enum detectorSettings setSettings(enum detectorSettings sett, int imod){ + //template setSettings() from mcb_funcs.c + //reads the dac registers from fpga to confirm which settings, if weird, undefined + + return OK; +} + +int startStateMachine(){ + //template startStateMachine() from firmware_funcs.c + /* + fifoReset(); + now_ptr=(char*)ram_values; + //send start acquisition to fpga + */ + return FAIL; +} + + +int stopStateMachine(){ + //template stopStateMachine() from firmware_funcs.c + // send stop to fpga + //if status = busy after 500us, return FAIL + return FAIL; +} + + +int startReadOut(){ + //template startReadOut() from firmware_funcs.c + //send fpga start readout + return FAIL; +} + + +enum runStatus getRunStatus(){ + //template runState() from firmware_funcs.c + //get status from fpga + return ERROR; +} + + +char *readFrame(int *ret, char *mess){ + //template fifo_read_event() from firmware_funcs.c + //checks if state machine running and if fifo has data(look_at_me_reg) and accordingly reads frame + // memcpy(now_ptr, values, dataBytes); + //returns ptr to values + return NULL; +} + + +int64_t setTimer(enum timerIndex ind, int64_t val){ + //template setDelay() from firmware_funcs.c + //writes to reg + //FRAME_NUMBER + //ACQUISITION_TIME + //FRAME_PERIOD + //DELAY_AFTER_TRIGGER + //GATES_NUMBER + //PROBES_NUMBER + //CYCLES_NUMBER + return 0; +} + + +int64_t getTimeLeft(enum timerIndex ind){ + //template getDelay() from firmware_funcs.c + //reads from reg + //FRAME_NUMBER + //ACQUISITION_TIME + //FRAME_PERIOD + //DELAY_AFTER_TRIGGER + //GATES_NUMBER + //PROBES_NUMBER + //CYCLES_NUMBER + return -1; +} + + +int setDynamicRange(int dr){ + //template setDynamicRange() from firmware_funcs.c + return 0; +} + + +enum readOutFlags setReadOutFlags(enum readOutFlags val){ + //template setStoreInRAM from firmware_funcs.c + return -1; +} + + + + +int setROI(int n, ROI arg[], int *retvalsize, int *ret){ + return FAIL; +} + + + +int setSpeed(enum speedVariable arg, int val){ + //template setClockDivider() from firmware_funcs.c + //CLOCK_DIVIDER + //WAIT_STATES + //SET_SIGNAL_LENGTH + //TOT_CLOCK_DIVIDER + //TOT_DUTY_CYCLE + + //returns eg getClockDivider from firmware_funcs.c + return 0; +} + + + +int executeTrimming(enum trimMode mode, int par1, int par2, int imod){ + // template trim_with_noise from trimming_funcs.c + return FAIL; +} + + + + +int configureMAC(int ipad, long long int imacadd, long long int iservermacadd, int dtb){ + //detector specific. + return FAIL; +} + + +int loadImage(enum imageType index, char *imageVals){ + //detector specific. + return FAIL; +} + + +int readCounterBlock(int startACQ, char *counterVals){ + //detector specific. + return FAIL; +} + +int resetCounterBlock(int startACQ){ + //detector specific. + return FAIL; +} + +int startReceiver(int d){ + + return 0; +} + +int calibratePedestal(int frames){ + + return 0; +} + +int calculateDataBytes(){ + return 0; +} + +int getTotalNumberOfChannels(){return 0;} +int getTotalNumberOfChips(){return 0;} +int getTotalNumberOfModules(){return 0;} +int getNumberOfChannelsPerChip(){return 0;} +int getNumberOfChannelsPerModule(){return 0;} +int getNumberOfChipsPerModule(){return 0;} +int getNumberOfDACsPerModule(){return 0;} +int getNumberOfADCsPerModule(){return 0;} + + + + + + + +enum externalSignalFlag getExtSignal(int signalindex){ + //template getExtSignal from firmware_funcs.c + //return signals[signalindex]; + return -1; +} + + + + + +enum externalSignalFlag setExtSignal(int signalindex, enum externalSignalFlag flag){ + //template setExtSignal from firmware_funcs.c + + //in short..sets signals array, checks if agrees with timing mode, writes to fpga reg, calls synchronization and then settiming + /* + if (signalindex>=0 && signalindex<4) { + signals[signalindex]=flag; +#ifdef VERBOSE + printf("settings signal variable number %d to value %04x\n", signalindex, signals[signalindex]); +#endif + // if output signal, set it! + switch (flag) { + case GATE_IN_ACTIVE_HIGH: + case GATE_IN_ACTIVE_LOW: + if (timingMode==GATE_FIX_NUMBER || timingMode==GATE_WITH_START_TRIGGER)//timingMode = AUTO_TIMING by default and is set in setTiming() + setFPGASignal(signalindex,flag); //not implemented here, checks if flag within limits and writes to fpga reg + else + setFPGASignal(signalindex,SIGNAL_OFF); + break; + case TRIGGER_IN_RISING_EDGE: + case TRIGGER_IN_FALLING_EDGE: + if (timingMode==TRIGGER_EXPOSURE || timingMode==GATE_WITH_START_TRIGGER) + setFPGASignal(signalindex,flag); + else + setFPGASignal(signalindex,SIGNAL_OFF); + break; + case RO_TRIGGER_IN_RISING_EDGE: + case RO_TRIGGER_IN_FALLING_EDGE: + if (timingMode==BURST_TRIGGER) + setFPGASignal(signalindex,flag); + else + setFPGASignal(signalindex,SIGNAL_OFF); + break; + case MASTER_SLAVE_SYNCHRONIZATION: + setSynchronization(syncMode);//syncmode = NO_SYNCHRONIZATION by default and set with this function + break; + default: + setFPGASignal(signalindex,mode); + } + + setTiming(GET_EXTERNAL_COMMUNICATION_MODE); + } + */ + return getExtSignal(signalindex); +} + + + + + + +enum externalCommunicationMode setTiming( enum externalCommunicationMode arg){ + //template setTiming from firmware_funcs.c + //template getFPGASignal from firmware_funcs.c + + + //getFPGASignal(signalindex) used later on in this fucntion + //gets flag from fpga reg, checks if flag within limits, + //if( flag=SIGNAL_OFF and signals[signalindex]==MASTER_SLAVE_SYNCHRONIZATION), return -1, (ensures masterslaveflag !=off now) + //else return flag + + int ret=GET_EXTERNAL_COMMUNICATION_MODE; + //sets timingmode variable + //ensures that the signals are in acceptance with timing mode and according sets the timing mode + /* + int g=-1, t=-1, rot=-1; + + int i; + + switch (ti) { + case AUTO_TIMING: + timingMode=ti; + // disable all gates/triggers in except if used for master/slave synchronization + for (i=0; i<4; i++) { + if (getFPGASignal(i)>0 && getFPGASignal(i)=0 && t>=0 && rot<0) { + ret=GATE_WITH_START_TRIGGER; + } else if (g<0 && t>=0 && rot<0) { + ret=TRIGGER_EXPOSURE; + } else if (g>=0 && t<0 && rot<0) { + ret=GATE_FIX_NUMBER; + } else if (g<0 && t<0 && rot>0) { + ret=TRIGGER_READOUT; + } else if (g<0 && t<0 && rot<0) { + ret=AUTO_TIMING; + } + + */ + return ret; +} + + + +enum masterFlags setMaster(enum masterFlags arg){ + //template setMaster from firmware_funcs.c + /* + int i; + switch(f) { + case NO_MASTER: + // switch of gates or triggers + masterMode=NO_MASTER; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + setFPGASignal(i,SIGNAL_OFF); + } + } + break; + case IS_MASTER: + // configure gate or trigger out + masterMode=IS_MASTER; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + setFPGASignal(i,SIGNAL_OFF); + break; + case MASTER_GATES: + setFPGASignal(i,GATE_OUT_ACTIVE_HIGH); + break; + case MASTER_TRIGGERS: + setFPGASignal(i,TRIGGER_OUT_RISING_EDGE); + break; + case SLAVE_STARTS_WHEN_MASTER_STOPS: + setFPGASignal(i,RO_TRIGGER_OUT_RISING_EDGE); + break; + default: + ; + } + } + } + break; + case IS_SLAVE: + // configure gate or trigger in + masterMode=IS_SLAVE; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + setFPGASignal(i,SIGNAL_OFF); + break; + case MASTER_GATES: + setFPGASignal(i,GATE_IN_ACTIVE_HIGH); + break; + case MASTER_TRIGGERS: + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + break; + case SLAVE_STARTS_WHEN_MASTER_STOPS: + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + break; + default: + ; + } + } + } + break; + default: + //do nothing + ; + } + + switch(masterMode) { + case NO_MASTER: + return NO_MASTER; + + + case IS_MASTER: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + return IS_MASTER; + case MASTER_GATES: + if (getFPGASignal(i)==GATE_OUT_ACTIVE_HIGH) + return IS_MASTER; + else + return NO_MASTER; + case MASTER_TRIGGERS: + if (getFPGASignal(i)==TRIGGER_OUT_RISING_EDGE) + return IS_MASTER; + else + return NO_MASTER; + case SLAVE_STARTS_WHEN_MASTER_STOPS: + if (getFPGASignal(i)==RO_TRIGGER_OUT_RISING_EDGE) + return IS_MASTER; + else + return NO_MASTER; + default: + return NO_MASTER; + } + + } + } + + case IS_SLAVE: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + switch (syncMode) { + case NO_SYNCHRONIZATION: + return IS_SLAVE; + case MASTER_GATES: + if (getFPGASignal(i)==GATE_IN_ACTIVE_HIGH) + return IS_SLAVE; + else + return NO_MASTER; + case MASTER_TRIGGERS: + case SLAVE_STARTS_WHEN_MASTER_STOPS: + if (getFPGASignal(i)==TRIGGER_IN_RISING_EDGE) + return IS_SLAVE; + else + return NO_MASTER; + default: + return NO_MASTER; + } + + } + } + + } + */ + + return NO_MASTER; +} + + + +enum synchronizationMode setSynchronization(enum synchronizationMode arg){ + /* + int i; + + switch(s) { + case NO_SYNCHRONIZATION: + syncMode=NO_SYNCHRONIZATION; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + setFPGASignal(i,SIGNAL_OFF); + } + } + break; + // disable external signals? + case MASTER_GATES: + // configure gate in or out + syncMode=MASTER_GATES; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER) + setFPGASignal(i,GATE_OUT_ACTIVE_HIGH); + else if (masterMode==IS_SLAVE) + setFPGASignal(i,GATE_IN_ACTIVE_HIGH); + } + } + + break; + case MASTER_TRIGGERS: + // configure trigger in or out + syncMode=MASTER_TRIGGERS; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER) + setFPGASignal(i,TRIGGER_OUT_RISING_EDGE); + else if (masterMode==IS_SLAVE) + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + } + } + break; + + + case SLAVE_STARTS_WHEN_MASTER_STOPS: + // configure trigger in or out + syncMode=SLAVE_STARTS_WHEN_MASTER_STOPS; + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER) + setFPGASignal(i,RO_TRIGGER_OUT_RISING_EDGE); + else if (masterMode==IS_SLAVE) + setFPGASignal(i,TRIGGER_IN_RISING_EDGE); + } + } + break; + + + default: + //do nothing + ; + } + + switch (syncMode) { + + case NO_SYNCHRONIZATION: + return NO_SYNCHRONIZATION; + + case MASTER_GATES: + + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER && getFPGASignal(i)==GATE_OUT_ACTIVE_HIGH) + return MASTER_GATES; + else if (masterMode==IS_SLAVE && getFPGASignal(i)==GATE_IN_ACTIVE_HIGH) + return MASTER_GATES; + } + } + return NO_SYNCHRONIZATION; + + case MASTER_TRIGGERS: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER && getFPGASignal(i)==TRIGGER_OUT_RISING_EDGE) + return MASTER_TRIGGERS; + else if (masterMode==IS_SLAVE && getFPGASignal(i)==TRIGGER_IN_RISING_EDGE) + return MASTER_TRIGGERS; + } + } + return NO_SYNCHRONIZATION; + + case SLAVE_STARTS_WHEN_MASTER_STOPS: + for (i=0; i<4; i++) { + if (signals[i]==MASTER_SLAVE_SYNCHRONIZATION) { + if (masterMode==IS_MASTER && getFPGASignal(i)==RO_TRIGGER_OUT_RISING_EDGE) + return SLAVE_STARTS_WHEN_MASTER_STOPS; + else if (masterMode==IS_SLAVE && getFPGASignal(i)==TRIGGER_IN_RISING_EDGE) + return SLAVE_STARTS_WHEN_MASTER_STOPS; + } + } + return NO_SYNCHRONIZATION; + + default: + return NO_SYNCHRONIZATION; + + } + + + */ + return NO_SYNCHRONIZATION; +} + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h new file mode 100644 index 000000000..1e1e13d40 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorFunctionList.h @@ -0,0 +1,165 @@ +#ifdef SLS_DETECTOR_FUNCTION_LIST + +#ifndef SLS_DETECTOR_FUNCTION_LIST_H +#define SLS_DETECTOR_FUNCTION_LIST_H + +#include "sls_detector_defs.h" +#include "slsDetectorServer_defs.h" + +#include + + + + +/**************************************************** +This functions are used by the slsDetectroServer_funcs interface. +Here are the definitions, but the actual implementation should be done for each single detector. + +****************************************************/ + + + +void getModuleConfiguration(); +int initDetector(); +int initDetectorStop(); + +int setNMod(int nm, enum dimension dim); +int getNModBoard(enum dimension arg); + +int64_t getModuleId(enum idMode arg, int imod); +int64_t getDetectorId(enum idMode arg); +int getDetectorNumber(); +u_int64_t getDetectorMAC(); +int getDetectorIP(); + +int moduleTest( enum digitalTestMode arg, int imod); +int detectorTest( enum digitalTestMode arg); + + +void setDAC(enum detDacIndex ind, int val, int imod, int mV, int retval[]); +int getADC(enum detAdcIndex ind, int imod); + + +#if defined(EIGERD) || defined(GOTTHARD) +int setHighVoltage(int val, int imod); +#endif + +#ifdef EIGERD +int setIODelay(int val, int imod); +int enableTenGigabitEthernet(int val); +int setCounterBit(int val); +int pulsePixel(int n, int x, int y); +int pulsePixelNMove(int n, int x, int y); +int pulseChip(int n); +int64_t setRateCorrection(int64_t custom_tau_in_nsec); +int getRateCorrectionEnable(); +int getDefaultSettingsTau_in_nsec(); +void setDefaultSettingsTau_in_nsec(int t); +int64_t getCurrentTau(); +#endif + +#if defined(MYTHEND) || defined(GOTTHARDD) +u_int32_t writeRegister(u_int32_t offset, u_int32_t data); +u_int32_t readRegister(u_int32_t offset); +#endif + +#ifdef MYTHEND +int setChannel(sls_detector_channel myChan); +int getChannel(sls_detector_channel *myChan); +int setChip(sls_detector_chip myChip); +int getChip(sls_detector_chip *myChip); +#endif + + +#ifdef EIGERD +int setModule(sls_detector_module myMod, int* gain, int* offset,int* delay); +int getModule(sls_detector_module *myMod, int* gain, int* offset); +#else +int setModule(sls_detector_module myMod); +int getModule(sls_detector_module *myMod); +#endif + + +enum detectorSettings setSettings(enum detectorSettings sett, int imod); +enum detectorSettings getSettings(); + +#if defined(MYTHEND) || defined(EIGERD) +int getThresholdEnergy(int imod); +int setThresholdEnergy(int ev, int imod); +#endif + +int startStateMachine(); +int stopStateMachine(); +int startReadOut(); +enum runStatus getRunStatus(); +char *readFrame(int *ret, char *mess); + + +int64_t setTimer(enum timerIndex ind, int64_t val); +int64_t getTimeLeft(enum timerIndex ind); + + +int setDynamicRange(int dr); +int setROI(int n, ROI arg[], int *retvalsize, int *ret); + + +#if defined(EIGERD) || defined(MYTHEND) +enum readOutFlags setReadOutFlags(enum readOutFlags val); +int setSpeed(enum speedVariable arg, int val); +int executeTrimming(enum trimMode mode, int par1, int par2, int imod); +#endif + + +#ifndef MYTHEND +int configureMAC(int ipad, long long int macad, long long int detectormacadd, int detipad, int udpport, int udpport2, int ival); +#endif + +#ifdef GOTTHARDD +int loadImage(enum imageType index, char *imageVals); +int readCounterBlock(int startACQ, char *counterVals); +int resetCounterBlock(int startACQ); +int startReceiver(int d); +int calibratePedestal(int frames); +#endif + + + + +int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod); + +int calculateDataBytes(); +int getTotalNumberOfChannels(); +int getTotalNumberOfChips(); +int getTotalNumberOfModules(); +int getNumberOfChannelsPerChip(); +int getNumberOfChannelsPerModule(); +int getNumberOfChipsPerModule(); +int getNumberOfDACsPerModule(); +int getNumberOfADCsPerModule(); +#ifdef EIGERD +int getNumberOfGainsPerModule(); +int getNumberOfOffsetsPerModule(); +#endif + +enum externalSignalFlag getExtSignal(int signalindex); +enum externalSignalFlag setExtSignal(int signalindex, enum externalSignalFlag flag); +enum externalCommunicationMode setTiming( enum externalCommunicationMode arg); +enum masterFlags setMaster(enum masterFlags arg); +enum synchronizationMode setSynchronization(enum synchronizationMode arg); + +#ifdef EIGERD +int startReceiver(int d); +void setExternalGating(int enable[]); +void setAllTrimbits(int val); +int getAllTrimbits(); +int getBebFPGATemp(); +int activate(int enable); +int setNetworkParameter(enum detNetworkParameter mode, int value); +#endif + + +#endif + + + +#endif diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer.c b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer.c new file mode 100755 index 000000000..f3f9b2631 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer.c @@ -0,0 +1,101 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ + +#include "sls_detector_defs.h" +#include "slsDetectorServer_defs.h" + +#include "communication_funcs.h" +#include "slsDetectorServer_funcs.h" + +#include +#include + + +extern int sockfd; + + +void error(char *msg){ + perror(msg); +} + +int main(int argc, char *argv[]){ + int portno, b; + int retval=OK; + int sd, fd; + +#ifdef STOP_SERVER + char cmd[100]; +#endif + if (argc==1) { + + checkFirmwareCompatibility(); +//#endif + portno = DEFAULT_PORTNO; + printf("opening control server on port %d\n",portno ); + b=1; +#ifdef STOP_SERVER + sprintf(cmd,"%s %d &",argv[0],DEFAULT_PORTNO+1); + system(cmd); +#endif + } else { + portno = DEFAULT_PORTNO+1; + if ( sscanf(argv[1],"%d",&portno) ==0) { + printf("could not open stop server: unknown port\n"); + return 1; + } + printf("opening stop server on port %d\n",portno); + b=0; + } +//#endif + + + init_detector(b); //defined in slsDetectorServer_funcs + + sd=bindSocket(portno); //defined in communication_funcs + + sockfd=sd; + + if (getServerError(sd)) { //defined in communication_funcs + printf("server error!\n"); + return -1; + } + + /* assign function table */ + function_table(); //defined in slsDetectorServer_funcs +#ifdef VERBOSE + printf("function table assigned \n"); +#endif + + + printf("\nReady...\n\n"); + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Waiting for client call\n"); +#endif + fd=acceptConnection(sockfd); //defined in communication_funcs +#ifdef VERY_VERBOSE + printf("Conenction accepted\n"); +#endif + if (fd>0) { + retval=decode_function(fd); //defined in slsDetectorServer_funcs +#ifdef VERY_VERBOSE + printf("function executed\n"); +#endif + closeConnection(fd); //defined in communication_funcs +#ifdef VERY_VERBOSE + printf("connection closed\n"); +#endif + } + } + + exitServer(sockfd); //defined in communication_funcs + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_defs.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_defs.h new file mode 100644 index 000000000..488dc0a0f --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_defs.h @@ -0,0 +1,37 @@ +/* + * slsDetectorServer_defs.h + * + * Created on: Jan 24, 2013 + * Author: l_maliakal_d + */ + +#ifndef SLSDETECTORSERVER_DEFS_H_ +#define SLSDETECTORSERVER_DEFS_H_ + +#include "sls_detector_defs.h" +#include + +#define GOODBYE -200 + + +/* examples*/ +#ifdef JUNGFRAU_DHANYA +#define NCHAN (256*256) +#define NCHIP 8 +#define NADC 0 +#else +#define NCHAN 1 +#define NCHIP 1 +#define NDAC 1 +#define NADC 1 +#endif + +#define NMAXMODX 1 +#define NMAXMODY 1 +#define NMAXMOD NMAXMODX*NMAXMODY +#define NCHANS NCHAN*NCHIP*NMAXMOD +#define NDACS NDAC*NMAXMOD + + + +#endif /* SLSDETECTORSERVER_DEFS_H_ */ diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c new file mode 100755 index 000000000..7bfad9fe9 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.c @@ -0,0 +1,4196 @@ + +#include "sls_detector_defs.h" +#include "slsDetectorServer_funcs.h" +#include "slsDetectorFunctionList.h" +#include "communication_funcs.h" + + +#include +#include + +#include +int sockfd; +extern int lockStatus; +extern char lastClientIP[INET_ADDRSTRLEN]; +extern char thisClientIP[INET_ADDRSTRLEN]; +extern int differentClients; + + + +// Global variables +int (*flist[256])(int); +//defined in the detector specific file +#ifdef MYTHEND +const enum detectorType myDetectorType=MYTHEN; +#elif GOTTHARDD +const enum detectorType myDetectorType=GOTTHARD; +#elif EIGERD +const enum detectorType myDetectorType=EIGER; +#elif PICASSOD +const enum detectorType myDetectorType=PICASSO; +#else +const enum detectorType myDetectorType=GENERIC; +#endif + +extern enum detectorSettings thisSettings; + +//global variables for optimized readout +char mess[MAX_STR_LENGTH]; +char *dataretval=NULL; +int dataret; +//extern +int dataBytes = 10; + + + +void checkFirmwareCompatibility(){ + int64_t fwversion = getDetectorId(DETECTOR_FIRMWARE_VERSION); + int64_t swversion = getDetectorId(DETECTOR_SOFTWARE_VERSION); + int64_t sw_fw_apiversion = getDetectorId(SOFTWARE_FIRMWARE_API_VERSION); + + cprintf(BLUE,"\n\n********************************************************\n" + "**********************EIGER Server**********************\n" + "********************************************************\n"); + cprintf(BLUE,"\n" + "Firmware Version:\t\t %lld\n" + "Software Version:\t\t %llx\n" + "F/w-S/w API Version:\t\t %lld\n" + "Required Firmware Version:\t %d\n" + "\n********************************************************\n", + fwversion,swversion,sw_fw_apiversion,REQUIRED_FIRMWARE_VERSION); + + //cant read versions + if(!fwversion || !sw_fw_apiversion){ + cprintf(RED,"FATAL ERROR: Cant read versions from FPGA. Please update firmware\n"); + cprintf(RED,"Exiting Server. Goodbye!\n\n"); + exit(-1); + } + + //check for API compatibility - old server + if(sw_fw_apiversion > REQUIRED_FIRMWARE_VERSION){ + cprintf(RED,"FATAL ERROR: This software version is incompatible.\n" + "Please update it to be compatible with this firmware\n\n"); + cprintf(RED,"Exiting Server. Goodbye!\n\n"); + exit(-1); + } + + //check for firmware compatibility - old firmware + if( REQUIRED_FIRMWARE_VERSION > fwversion){ + cprintf(RED,"FATAL ERROR: This firmware version is incompatible.\n" + "Please update it to v%d to be compatible with this server\n\n", REQUIRED_FIRMWARE_VERSION); + cprintf(RED,"Exiting Server. Goodbye!\n\n"); + exit(-1); + } +} + + +int init_detector(int b) { +#ifdef VIRTUAL + printf("This is a VIRTUAL detector\n"); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if(b) initDetector(); + else initDetectorStop(); +#endif + strcpy(mess,"dummy message"); + strcpy(lastClientIP,"none"); + strcpy(thisClientIP,"none1"); + lockStatus=0; + return OK; +} + + +int decode_function(int file_des) { + int fnum,n; + int ret=FAIL; +#ifdef VERBOSE + printf( "receive data\n"); +#endif + n = receiveData(file_des,&fnum,sizeof(fnum),INT32); + if (n <= 0) { +#ifdef VERBOSE + printf("ERROR reading from socket %d, %d %d\n", n, fnum, file_des); +#endif + return FAIL; + } +#ifdef VERBOSE + else + printf("size of data received %d\n",n); +#endif + +#ifdef VERBOSE + printf( "calling function fnum = %d %x\n",fnum,(unsigned int)flist[fnum]); +#endif + if (fnum<0 || fnum>255) + fnum=255; + ret=(*flist[fnum])(file_des); + if (ret==FAIL) + cprintf( RED, "Error executing the function = %d \n",fnum); + return ret; +} + + +int function_table() { + int i; + for (i=0;i<256;i++){ + flist[i]=&M_nofunc; + } + flist[F_EXIT_SERVER]=&exit_server; + flist[F_EXEC_COMMAND]=&exec_command; + + flist[F_LOCK_SERVER]=&lock_server; + flist[F_GET_LAST_CLIENT_IP]=&get_last_client_ip; + flist[F_SET_PORT]=&set_port; + flist[F_UPDATE_CLIENT]=&update_client; + flist[F_SET_MASTER]=&set_master; + flist[F_SET_SYNCHRONIZATION_MODE]=&set_synchronization; + + //F_GET_ERROR + flist[F_GET_DETECTOR_TYPE]=&get_detector_type; + flist[F_SET_NUMBER_OF_MODULES]=&set_number_of_modules; + flist[F_GET_MAX_NUMBER_OF_MODULES]=&get_max_number_of_modules; + flist[F_SET_EXTERNAL_SIGNAL_FLAG]=&set_external_signal_flag; + flist[F_SET_EXTERNAL_COMMUNICATION_MODE]=&set_external_communication_mode; + flist[F_GET_ID]=&get_id; + flist[F_DIGITAL_TEST]=&digital_test; + //F_ANALOG_TEST + //F_ENABLE_ANALOG_OUT + //F_CALIBRATION_PULSE + flist[F_SET_DAC]=&set_dac; + flist[F_GET_ADC]=&get_adc; + flist[F_WRITE_REGISTER]=&write_register; + flist[F_READ_REGISTER]=&read_register; + //F_WRITE_MEMORY + //F_READ_MEMORY + flist[F_SET_CHANNEL]=&set_channel; + flist[F_GET_CHANNEL]=&get_channel; + //F_SET_ALL_CHANNELS + flist[F_SET_CHIP]=&set_chip; + flist[F_GET_CHIP]=&get_chip; + //F_SET_ALL_CHIPS + flist[F_SET_MODULE]=&set_module; + flist[F_GET_MODULE]=&get_module; + //F_SET_ALL_MODULES + flist[F_SET_SETTINGS]=&set_settings; + flist[F_GET_THRESHOLD_ENERGY]=&get_threshold_energy; + flist[F_SET_THRESHOLD_ENERGY]=&set_threshold_energy; + flist[F_START_ACQUISITION]=&start_acquisition; + flist[F_STOP_ACQUISITION]=&stop_acquisition; + flist[F_START_READOUT]=&start_readout; + flist[F_GET_RUN_STATUS]=&get_run_status; + flist[F_START_AND_READ_ALL]=&start_and_read_all; + flist[F_READ_FRAME]=&read_frame; + flist[F_READ_ALL]=&read_all; + flist[F_SET_TIMER]=&set_timer; + flist[F_GET_TIME_LEFT]=&get_time_left; + flist[F_SET_DYNAMIC_RANGE]=&set_dynamic_range; + flist[F_SET_READOUT_FLAGS]=&set_readout_flags; + flist[F_SET_ROI]=&set_roi; + flist[F_SET_SPEED]=&set_speed; + flist[F_EXECUTE_TRIMMING]=&execute_trimming; + flist[F_CONFIGURE_MAC]=&configure_mac; + flist[F_LOAD_IMAGE]=&load_image; + flist[F_READ_COUNTER_BLOCK]=&read_counter_block; + flist[F_RESET_COUNTER_BLOCK]=&reset_counter_block; + flist[F_START_RECEIVER]=&start_receiver; + flist[F_STOP_RECEIVER]=&stop_receiver; + flist[F_CALIBRATE_PEDESTAL]=&calibrate_pedestal; + flist[F_ENABLE_TEN_GIGA]=&enable_ten_giga; + flist[F_SET_ALL_TRIMBITS]=&set_all_trimbits; + flist[F_SET_COUNTER_BIT]=&set_counter_bit; + flist[F_PULSE_PIXEL]=&pulse_pixel; + flist[F_PULSE_PIXEL_AND_MOVE]=&pulse_pixel_and_move; + flist[F_PULSE_CHIP]=&pulse_chip; + flist[F_SET_RATE_CORRECT]=&set_rate_correct; + flist[F_GET_RATE_CORRECT]=&get_rate_correct; + flist[F_ACTIVATE]=&set_activate; + flist[F_SET_NETWORK_PARAMETER]=&set_network_parameter; + + +#ifdef VERBOSE + /* for (i=0;i<256;i++){ + printf("function %d located at %x\n",i,flist[i]); + }*/ +#endif + return OK; +} + + +int M_nofunc(int file_des){ + + int ret=FAIL; + sprintf(mess,"Unrecognized Function\n"); + printf(mess); + sendData(file_des,&ret,sizeof(ret),INT32); + sendData(file_des,mess,sizeof(mess),OTHER); + return GOODBYE; +} + + +int exit_server(int file_des) { + int ret=FAIL; + sendData(file_des,&ret,sizeof(ret),INT32); + printf("closing server."); + sprintf(mess,"closing server"); + sendData(file_des,mess,sizeof(mess),OTHER); + return GOODBYE; +} + +int exec_command(int file_des) { + char cmd[MAX_STR_LENGTH]; + char answer[MAX_STR_LENGTH]; + int ret=OK,ret1=OK; + int sysret=0; + int n=0; + + /* receive arguments */ + n = receiveData(file_des,cmd,MAX_STR_LENGTH,OTHER); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + /* execute action if the arguments correctly arrived*/ + if (ret==OK) { +#ifdef VERBOSE + printf("executing command %s\n", cmd); +#endif + if (lockStatus==0 || differentClients==0) + sysret=system(cmd); + + //should be replaced by popen + if (sysret==0) { + sprintf(answer,"Succeeded\n"); + if (lockStatus==1 && differentClients==1) + sprintf(answer,"Detector locked by %s\n", lastClientIP); + } else { + sprintf(answer,"Failed\n"); + ret=FAIL; + } + } else { + sprintf(answer,"Could not receive the command\n"); + } + + /* send answer */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + n = sendData(file_des,answer,MAX_STR_LENGTH,OTHER); + if (n < 0) { + sprintf(mess,"Error writing to socket"); + ret=FAIL; + } + + + /*return ok/fail*/ + return ret; + +} + + + + + +int lock_server(int file_des) { + + + int n; + int ret=OK,ret1=OK; + + + int lock; + n = receiveData(file_des,&lock,sizeof(lock),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (lock)\n"); + ret=FAIL; + } + if (lock>=0) { + if (lockStatus==0 || strcmp(lastClientIP,thisClientIP)==0 || strcmp(lastClientIP,"none")==0) { + lockStatus=lock; + strcpy(lastClientIP,thisClientIP); + } else { + ret=FAIL; + sprintf(mess,"Server already locked by %s\n", lastClientIP); + } + } + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else + n = sendData(file_des,&lockStatus,sizeof(lockStatus),INT32); + + return ret; + +} + + + + +int get_last_client_ip(int file_des) { + int ret=OK,ret1=OK; + if (differentClients ) + ret=FORCE_UPDATE; + sendData(file_des,&ret1,sizeof(ret),INT32); + sendData(file_des,lastClientIP,sizeof(lastClientIP),OTHER); + return ret; +} + + + + +int set_port(int file_des) { + int n; + int ret=OK,ret1=OK; + int sd=-1; + + enum portType p_type; /** data? control? stop? Unused! */ + int p_number; /** new port number */ + + n = receiveData(file_des,&p_type,sizeof(p_type),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (ptype)\n"); + ret=FAIL; + } + + n = receiveData(file_des,&p_number,sizeof(p_number),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (pnum)\n"); + ret=FAIL; + } + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + if (p_number<1024) { + sprintf(mess,"Too low port number %d\n", p_number); + printf("\n"); + ret=FAIL; + } + + printf("set port %d to %d\n",p_type, p_number); + + sd=bindSocket(p_number); + } + if (sd>=0) { + ret=OK; + if (differentClients ) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Could not bind port %d\n", p_number); + printf("Could not bind port %d\n", p_number); + if (sd==-10) { + sprintf(mess,"Port %d already set\n", p_number); + printf("Port %d already set\n", p_number); + + } + } + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&p_number,sizeof(p_number),INT32); + closeConnection(file_des); + exitServer(sockfd); + sockfd=sd; + + } + + return ret; + +} + + + +int send_update(int file_des) { + + enum detectorSettings t; + int n = 0, nm = 0; + int64_t retval = 0; + + n += sendData(file_des,lastClientIP,sizeof(lastClientIP),OTHER); +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=setNMod(GET_FLAG,X); +#endif + n += sendData(file_des,&nm,sizeof(nm),INT32); +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=setNMod(GET_FLAG,Y); +#endif + n += sendData(file_des,&nm,sizeof(nm),INT32); +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=setDynamicRange(GET_FLAG); +#endif + n += sendData(file_des,&nm,sizeof(nm),INT32); + nm = dataBytes; + n += sendData(file_des,&nm,sizeof(nm),INT32); +#ifdef SLS_DETECTOR_FUNCTION_LIST + t=setSettings(GET_SETTINGS, GET_FLAG); +#endif + n += sendData(file_des,&t,sizeof(t),INT32); +#ifdef SLS_DETECTOR_FUNCTION_LIST + nm=getThresholdEnergy(GET_FLAG); +#endif + n += sendData(file_des,&nm,sizeof(nm),INT32); +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(FRAME_NUMBER,GET_FLAG); +#endif + n += sendData(file_des,&retval,sizeof(int64_t),INT64); +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(ACQUISITION_TIME,GET_FLAG); +#endif + n += sendData(file_des,&retval,sizeof(int64_t),INT64); +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(SUBFRAME_ACQUISITION_TIME,GET_FLAG); +#endif + n += sendData(file_des,&retval,sizeof(int64_t),INT64); +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(FRAME_PERIOD,GET_FLAG); +#endif + n += sendData(file_des,&retval,sizeof(int64_t),INT64); +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(DELAY_AFTER_TRIGGER,GET_FLAG); +#endif + n += sendData(file_des,&retval,sizeof(int64_t),INT64); +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(GATES_NUMBER,GET_FLAG); +#endif + n += sendData(file_des,&retval,sizeof(int64_t),INT64); +/* retval=setTimer(PROBES_NUMBER,GET_FLAG); + n += sendData(file_des,&retval,sizeof(int64_t),INT64);*/ +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=setTimer(CYCLES_NUMBER,GET_FLAG); +#endif + n += sendData(file_des,&retval,sizeof(int64_t),INT64); + + if (lockStatus==0) { + strcpy(lastClientIP,thisClientIP); + } + + return OK; + +} + + +int update_client(int file_des) { + + int ret=OK; + sendData(file_des,&ret,sizeof(ret),INT32); + return send_update(file_des); + +} + + + + +int set_master(int file_des) { + + enum masterFlags retval=GET_MASTER; + enum masterFlags arg; + int n; + int ret=OK,ret1=OK; + // int regret=OK; + + + sprintf(mess,"can't set master flags\n"); + + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1 && ((int)arg!=(int)GET_READOUT_FLAGS)) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setMaster(arg); + + } +#endif + if (retval==GET_MASTER) { + ret=FAIL; + } + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&retval,sizeof(retval),INT32); + } + return ret; +} + + + + + + +int set_synchronization(int file_des) { + + enum synchronizationMode retval=GET_SYNCHRONIZATION_MODE; + enum synchronizationMode arg; + int n; + int ret=OK,ret1=OK; + //int regret=OK; + + + sprintf(mess,"can't set synchronization mode\n"); + + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef VERBOSE + printf("setting master flags to %d\n",arg); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1 && ((int)arg!=(int)GET_READOUT_FLAGS)) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setSynchronization(arg); + } +#endif + + if (retval==GET_SYNCHRONIZATION_MODE) { + ret=FAIL; + } + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&retval,sizeof(retval),INT32); + } + return ret; +} + + + + + + + +int get_detector_type(int file_des) { + int n=0; + enum detectorType retval; + int ret=OK,ret1=OK; + + sprintf(mess,"Can't return detector type\n"); + + + /* receive arguments */ + /* execute action */ + retval=myDetectorType; + +#ifdef VERBOSE + printf("Returning detector type %d\n",retval); +#endif + + /* send answer */ + /* send OK/failed */ + if (differentClients==1) + ret=FORCE_UPDATE; + + //ret could be swapped during sendData + ret1 = ret; + n += sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + /*return ok/fail*/ + return ret; + + +} + + +int set_number_of_modules(int file_des) { + int n; + int arg[2], retval=0; + int ret=OK,ret1=OK; + int nm; +#ifdef SLS_DETECTOR_FUNCTION_LIST + enum dimension dim; +#endif + sprintf(mess,"Can't set number of modules\n"); + + /* receive arguments */ + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket %d", n); + ret=GOODBYE; + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + dim=arg[0]; + nm=arg[1]; + + /* execute action */ +#ifdef VERBOSE + printf("Setting the number of modules in dimension %d to %d\n",dim,nm ); +#endif + if (lockStatus==1 && differentClients==1 && nm!=GET_FLAG) { + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } else + retval=setNMod(nm, dim); + } + dataBytes=calculateDataBytes(); +#endif + + if (retval==nm || nm==GET_FLAG) { + ret=OK; + if (differentClients==1) + ret=FORCE_UPDATE; + } else + ret=FAIL; + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; +} + + +int get_max_number_of_modules(int file_des) { + int n; + int retval; + int ret=OK,ret1=OK; + enum dimension arg; + + sprintf(mess,"Can't get max number of modules\n"); + /* receive arguments */ + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + /* execute action */ +#ifdef VERBOSE + printf("Getting the max number of modules in dimension %d \n",arg); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + + retval=getNModBoard(arg); +#endif +#ifdef VERBOSE + printf("Max number of module in dimension %d is %d\n",arg,retval ); +#endif + + if (differentClients==1 && ret==OK) { + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; +} + + +//index 0 is in gate +//index 1 is in trigger +//index 2 is out gate +//index 3 is out trigger + +int set_external_signal_flag(int file_des) { + int n; + int arg[2]; + int ret=OK,ret1=OK; + enum externalSignalFlag retval=SIGNAL_OFF; +#ifdef SLS_DETECTOR_FUNCTION_LIST + int signalindex; + enum externalSignalFlag flag; +#endif + + sprintf(mess,"Can't set external signal flag\n"); + + /* receive arguments */ + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + signalindex=arg[0]; + flag=arg[1]; + /* execute action */ + switch (flag) { + case GET_EXTERNAL_SIGNAL_FLAG: + retval=getExtSignal(signalindex); + break; + default: + if (differentClients==0 || lockStatus==0) { + retval=setExtSignal(signalindex,flag); + if (retval!=flag) { + ret=FAIL; + sprintf(mess,"External signal %d flag should be 0x%04x but is 0x%04x\n", signalindex, flag, retval); + } + + } else if (lockStatus!=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n", lastClientIP); + } + break; + } +#ifdef VERBOSE + printf("Setting external signal %d to flag %d\n",signalindex,flag ); + printf("Set to flag %d\n",retval); +#endif + } else { + ret=FAIL; + } +#endif + + if (ret==OK && differentClients!=0) + ret=FORCE_UPDATE; + + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + + /*return ok/fail*/ + return ret; + +} + + +int set_external_communication_mode(int file_des) { + int n; + enum externalCommunicationMode arg, retval=GET_EXTERNAL_COMMUNICATION_MODE; + int ret=OK,ret1=OK; + + sprintf(mess,"Can't set external communication mode\n"); + + + /* receive arguments */ + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + /* +enum externalCommunicationMode{ + GET_EXTERNAL_COMMUNICATION_MODE, + AUTO, + TRIGGER_EXPOSURE_SERIES, + TRIGGER_EXPOSURE_BURST, + TRIGGER_READOUT, + TRIGGER_COINCIDENCE_WITH_INTERNAL_ENABLE, + GATE_FIX_NUMBER, + GATE_FIX_DURATION, + GATE_WITH_START_TRIGGER, + // GATE_COINCIDENCE_WITH_INTERNAL_ENABLE, + BURST_TRIGGER +}; + */ +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + /* execute action */ + switch(arg){ +#ifdef EIGERD + case GET_EXTERNAL_COMMUNICATION_MODE: + case AUTO_TIMING: + case TRIGGER_EXPOSURE: + case BURST_TRIGGER: + case GATE_FIX_NUMBER: + break; +#endif + default: + ret = FAIL; + sprintf(mess,"This timing mode %d not implemented in this detector\n",(int)arg); + break; + } + } + if (ret==OK) { +#ifdef VERBOSE + printf("Setting external communication mode to %d\n", arg); +#endif + retval=setTiming(arg); + + if (differentClients==1) + ret=FORCE_UPDATE; + } +#endif + + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; + + +} + + + +int get_id(int file_des) { + // sends back 64 bits! + int64_t retval; + int ret=OK,ret1=OK; +#ifndef EIGERD + int imod=-1; +#endif + int n=0; + enum idMode arg; + + sprintf(mess,"Can't return id\n"); + + /* receive arguments */ + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Getting id %d\n", arg); +#endif + + switch (arg) { +#ifndef EIGERD + case MODULE_SERIAL_NUMBER: + case MODULE_FIRMWARE_VERSION: + n = receiveData(file_des,&imod,sizeof(imod),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { +#ifdef VERBOSE + printf("of module %d\n", imod); +#endif + if (imod>=0 && imod=0 && imod=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + } +#endif + + // check if dac exists for this detector + switch (ind) { +#ifdef MYTHEND + case TRIMBIT_SIZE: //ind = VTRIM; + break; + case THRESHOLD: + break; + case SHAPER1: + break; + case SHAPER2: + break; + case CALIBRATION_PULSE: + break; + case PREAMP: + break; +#endif +#ifdef GOTTHARDD + case G_VREF_DS : + break; + case G_VCASCN_PB: + break; + case G_VCASCP_PB: + break; + case G_VOUT_CM: + break; + case G_VCASC_OUT: + break; + case G_VIN_CM: + break; + case G_VREF_COMP: + break; + case G_IB_TESTC: + break; + case HV_POT: + break; +#endif +#ifdef EIGERD + case TRIMBIT_SIZE: + idac = VTR; + break; + case THRESHOLD: + idac = VTHRESHOLD; + break; + case E_SvP: + idac = SVP; + break; + case E_SvN: + idac = SVN; + break; + case E_Vtr: + idac = VTR; + break; + case E_Vrf: + idac = VRF; + break; + case E_Vrs: + idac = VRS; + break; + case E_Vtgstv: + idac = VTGSTV; + break; + case E_Vcmp_ll: + idac = VCMP_LL; + break; + case E_Vcmp_lr: + idac = VCMP_LR; + break; + case E_cal: + idac = CAL; + break; + case E_Vcmp_rl: + idac = VCMP_RL; + break; + case E_Vcmp_rr: + idac = VCMP_RR; + break; + case E_rxb_rb: + idac = RXB_RB; + break; + case E_rxb_lb: + idac = RXB_LB; + break; + case E_Vcp: + idac = VCP; + break; + case E_Vcn: + idac = VCN; + break; + case E_Vis: + idac = VIS; + break; + case HV_NEW: + break; + case IO_DELAY: + break; +#endif + default: + printf("Unknown DAC index %d\n",(int)ind); + sprintf(mess,"Unknown DAC index %d for this detector\n",ind); + ret=FAIL; + break; + } +#ifdef VERBOSE + printf("Setting DAC %d of module %d to %d \n", idac, imod, val); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1 && val!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + if((ind == HV_POT) ||(ind == HV_NEW)) + retval[0] = setHighVoltage(val,imod); + else if(ind == IO_DELAY) + retval[0] = setIODelay(val,imod); + else + setDAC(idac,val,imod,mV,retval); + } + + + + } +#endif +#ifdef VERBOSE + printf("DAC set to %d in dac units and %d mV\n", retval[0],retval[1]); +#endif + + if(ret == OK){ + if(mV) + temp = retval[1]; + else + temp = retval[0]; + if ((abs(temp-val)<=5) || val==-1) { + ret=OK; + if (differentClients) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + printf("Setting dac %d of module %d: wrote %d but read %d\n", idac, imod, val, temp); + } + } + + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /* Maybe this is done inside the initialization funcs */ + //detectorDacs[imod][ind]=val; + /*return ok/fail*/ + return ret; + +} + + + +int get_adc(int file_des) { + + int retval=-1; + int ret=OK,ret1=OK; + int arg[2]; + enum dacIndex ind; + int imod; + int n; + enum detAdcIndex iadc=0; + + sprintf(mess,"Can't read ADC\n"); + + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + ind=arg[0]; + imod=arg[1]; + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules() || imod<0) { + ret=FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + } +#endif + switch (ind) { +#ifdef EIGERD + case TEMPERATURE_FPGAEXT: + iadc = TEMP_FPGAEXT; + break; + case TEMPERATURE_10GE: + iadc = TEMP_10GE; + break; + case TEMPERATURE_DCDC: + iadc = TEMP_DCDC; + break; + case TEMPERATURE_SODL: + iadc = TEMP_SODL; + break; + case TEMPERATURE_SODR: + iadc = TEMP_SODR; + break; + case TEMPERATURE_FPGA: + iadc = TEMP_FPGA; + break; + case TEMPERATURE_FPGA2: + iadc = TEMP_FPGAFEBL; + break; + case TEMPERATURE_FPGA3: + iadc = TEMP_FPGAFEBR; + break; +#endif +#ifdef GOTTHARDD + case TEMPERATURE_FPGA: + break; + case TEMPERATURE_ADC: + break; +#endif + default: + printf("Unknown DAC index %d\n",ind); + ret=FAIL; + sprintf(mess,"Unknown ADC index %d. Not implemented for this detector\n",ind); + break; + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + retval=getADC(iadc,imod); + } +#endif +#ifdef VERBOSE + printf("Getting ADC %d of module %d\n", iadc, imod); +#endif + +#ifdef VERBOSE + printf("ADC is %f V\n", retval); +#endif + if (ret==FAIL) { + printf("Getting adc %d of module %d failed\n", iadc, imod); + } + + + if (differentClients) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; + +} + + + + + + +int write_register(int file_des) { + + int retval; + int ret=OK,ret1=OK; + int arg[2]; + int addr, val; + int n; + + + sprintf(mess,"Can't write to register\n"); + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + addr=arg[0]; + val=arg[1]; + +#if defined(MYTHEND) || defined(GOTTHARDD) +#ifdef VERBOSE + printf("writing to register 0x%x data 0x%x\n", addr, val); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + retval=writeRegister(addr,val); +#endif +#ifdef VERBOSE + printf("Data set to 0x%x\n", retval); +#endif +#else + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#endif + if (retval==val) { + ret=OK; + if (differentClients) + ret=FORCE_UPDATE; + } else { + ret=FAIL; + sprintf(mess,"Writing to register 0x%x failed: wrote 0x%x but read 0x%x\n", addr, val, retval); + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; + +} + +int read_register(int file_des) { + + int retval; + int ret=OK,ret1=OK; + int arg; + int addr; + int n; + + + sprintf(mess,"Can't read register\n"); + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + addr=arg; + +#if defined(MYTHEND) || defined(GOTTHARDD) +#ifdef VERBOSE + printf("reading register 0x%x\n", addr); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval=readRegister(addr); +#endif +#ifdef VERBOSE + printf("Returned value 0x%x\n", retval); +#endif +#else + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#endif + + if (ret==FAIL) { + printf("Reading register 0x%x failed\n", addr); + } else if (differentClients) + ret=FORCE_UPDATE; + + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; + +} + + + + + + +int set_channel(int file_des) { + int ret=OK,ret1=OK; + sls_detector_channel myChan; + int retval; + int n; + + + sprintf(mess,"Can't set channel\n"); + +#ifdef VERBOSE + printf("Setting channel\n"); +#endif + ret=receiveChannel(file_des, &myChan); + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifndef MYTHEND + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef VERBOSE + printf("channel number is %d, chip number is %d, module number is %d, register is %lld\n", myChan.chan,myChan.chip, myChan.module, myChan.reg); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (myChan.chan>=getNumberOfChannelsPerChip()) { + ret=FAIL; + sprintf(mess, "channel number %d too large!\n",myChan.chan); + } + if (myChan.chip>=getNumberOfChipsPerModule()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",myChan.chip); + } + + if (myChan.module>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",myChan.module); + } + + + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setChannel(myChan); + } + } +#endif +#endif + /* Maybe this is done inside the initialization funcs */ + //copyChannel(detectorChans[myChan.module][myChan.chip]+(myChan.chan), &myChan); + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + + /*return ok/fail*/ + return ret; + +} + + + + +int get_channel(int file_des) { + + int ret=OK,ret1=OK; + sls_detector_channel retval; + + int arg[3]; +#ifdef MYTHEND + int ichan, ichip, imod; +#endif + int n; + + sprintf(mess,"Can't get channel\n"); + + + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifndef MYTHEND + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else + ichan=arg[0]; + ichip=arg[1]; + imod=arg[2]; +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ichan>=getNumberOfChannelsPerChip()) { + ret=FAIL; + sprintf(mess, "channel number %d too large!\n",ichan); + } else + retval.chan=ichan; + if (ichip>=getNumberOfChipsPerModule()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",ichip); + } else + retval.chip=ichip; + + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",imod); + } else + retval.module=imod; + + + if (ret==OK) + ret=getChannel(&retval); +#endif +#endif + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + +#ifdef MYTHEND +#ifdef VERBOSE + printf("Returning channel %d %d %d, 0x%llx\n", retval.chan, retval.chip, retval.mod, (retval.reg)); +#endif +#endif + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + ret=sendChannel(file_des, &retval); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + + + /*return ok/fail*/ + return ret; + + +} + + +int set_chip(int file_des) { + + int *ch; + int n, retval; + int ret=OK,ret1=OK; +#ifdef SLS_DETECTOR_FUNCTION_LIST + sls_detector_chip myChip; + + myChip.nchan=getNumberOfChannelsPerChip(); + ch=(int*)malloc((myChip.nchan)*sizeof(int)); + myChip.chanregs=ch; + + + +#ifdef VERBOSE + printf("Setting chip\n"); +#endif + ret=receiveChip(file_des, &myChip); + +#ifndef MYTHEND + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef VERBOSE + printf("Chip received\n"); +#endif + if (ret>=0) + ret=OK; + else + ret=FAIL; +#ifdef VERBOSE + printf("chip number is %d, module number is %d, register is %d, nchan %d\n",myChip.chip, myChip.module, myChip.reg, myChip.nchan); +#endif + + if (myChip.chip>=getNumberOfChipsPerModule()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",myChip.chip); + } + + if (myChip.module>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",myChip.module); + } + + + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setChip(myChip); + } +#endif +#endif + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + if (differentClients && ret==OK) + ret=FORCE_UPDATE; + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + free(ch); + + return ret; +} + + + + +int get_chip(int file_des) { + + + int ret=OK,ret1=OK; + sls_detector_chip retval; + int arg[2]; + int n, *ch; +#ifdef MYTHEND + int ichip, imod; +#endif + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + retval.nchan=getNumberOfChannelsPerChip(); + ch=(int*)malloc((retval.nchan)*sizeof(int)); + retval.chanregs=ch; +#endif + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifndef MYTHEND + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else + ichip=arg[0]; + imod=arg[1]; +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ichip>=getNumberOfChipsPerModule()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",ichip); + } else + retval.chip=ichip; + + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess, "chip number %d too large!\n",imod); + } else + retval.module=imod; + + if (ret==OK) + ret=getChip(&retval); +#endif + +#endif + if (differentClients && ret==OK) + ret=FORCE_UPDATE; +#ifdef MYTHEND +#ifdef VERBOSE + printf("Returning chip %d %d\n", ichip, imod); +#endif +#endif + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + ret=sendChip(file_des, &retval); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + free(ch); + + /*return ok/fail*/ + return ret; + + +} + + + + + +int set_module(int file_des) { + int retval, n; + int ret=OK,ret1=OK; + + strcpy(mess,"could not set module."); + +#ifdef SLS_DETECTOR_FUNCTION_LIST + sls_detector_module myModule; +#ifdef EIGERD + int *myGain = (int*)malloc(getNumberOfGainsPerModule()*sizeof(int)); + int *myOffset = (int*)malloc(getNumberOfOffsetsPerModule()*sizeof(int)); + int *myIODelay = (int*)malloc(sizeof(int)); + int64_t myTau=-1; +#endif + int *myChip=(int*)malloc(getNumberOfChipsPerModule()*sizeof(int)); + int *myChan=(int*)malloc(getNumberOfChannelsPerModule()*sizeof(int)); + int *myDac=(int*)malloc(getNumberOfDACsPerModule()*sizeof(int)); + int *myAdc=(int*)malloc(getNumberOfADCsPerModule()*sizeof(int)); + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } +#ifdef EIGERD + if (!myGain){ + sprintf(mess,"could not allocate gains\n"); + ret=FAIL; + } + if (!myOffset){ + sprintf(mess,"could not allocate offsets\n"); + ret=FAIL; + } +#endif + myModule.nchip=getNumberOfChipsPerModule(); + myModule.nchan=getNumberOfChannelsPerModule(); + myModule.ndac=getNumberOfDACsPerModule(); + myModule.nadc=getNumberOfADCsPerModule(); + + +#ifdef VERBOSE + printf("Setting module\n"); +#endif + ret=receiveModule(file_des, &myModule); +#ifdef EIGERD + n = receiveData(file_des,myGain,sizeof(int)*getNumberOfGainsPerModule(),INT32); + n = receiveData(file_des,myOffset,sizeof(int)*getNumberOfOffsetsPerModule(),INT32); + n = receiveData(file_des,myIODelay,sizeof(int),INT32); + n = receiveData(file_des,&myTau,sizeof(myTau),INT64); +#endif + if (ret>=0) + ret=OK; + else + ret=FAIL; + + +#ifdef VERBOSE + printf("module number is %d,register is %d, nchan %d, nchip %d, ndac %d, nadc %d, gain %f, offset %f\n",myModule.module, myModule.reg, myModule.nchan, myModule.nchip, myModule.ndac, myModule.nadc, myModule.gain,myModule.offset); +#ifdef EIGERD + int i; + for(i=0;i -2){ //ignore -2: from load settings) + + //set default tau value (-1 or a normal value) + setDefaultSettingsTau_in_nsec(myTau); + + //switch off rate correction: no value read from load calib/load settings) + if(myTau == -1){ + if(getRateCorrectionEnable()){ + ret = FAIL; + setRateCorrection(0); + strcat(mess,"Cannot set Rate correction. No default tau provided. Deactivating Rate Correction\n"); + cprintf(RED,"%s",mess); + } + } + + + //normal tau value (only if enabled) + else if (getRateCorrectionEnable()){ + int64_t retvalTau = setRateCorrection(myTau); //myTau will not be -1 here + if(myTau != retvalTau){ + cprintf(RED,"%s",mess); + ret=FAIL; + } + } + } + retval = getSettings(); + +#else + ret=setModule(myModule); + retval = ret; +#endif + } + } +#endif + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* Maybe this is done inside the initialization funcs */ + //copyChip(detectorChips[myChip.module]+(myChip.chip), &myChip); + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + free(myChip); + free(myChan); + free(myDac); + free(myAdc); +#ifdef EIGERD + free(myGain); + free(myOffset); +#endif +#endif + return ret; +} + + + + +int get_module(int file_des) { + + + int ret=OK,ret1=OK; + int arg; + int imod; + int n; + sls_detector_module myModule; + +#ifdef SLS_DETECTOR_FUNCTION_LIST +#ifdef EIGERD + int *myGain = (int*)malloc(getNumberOfGainsPerModule()*sizeof(int)); + int *myOffset = (int*)malloc(getNumberOfOffsetsPerModule()*sizeof(int)); +#endif + int *myChip=(int*)malloc(getNumberOfChipsPerModule()*sizeof(int)); + int *myChan=(int*)malloc(getNumberOfChannelsPerModule()*sizeof(int)); + int *myDac=(int*)malloc(getNumberOfDACsPerModule()*sizeof(int)); + int *myAdc=(int*)malloc(getNumberOfADCsPerModule()*sizeof(int)); + + + if (myDac) + myModule.dacs=myDac; + else { + sprintf(mess,"could not allocate dacs\n"); + ret=FAIL; + } + if (myAdc) + myModule.adcs=myAdc; + else { + sprintf(mess,"could not allocate adcs\n"); + ret=FAIL; + } + if (myChip) + myModule.chipregs=myChip; + else { + sprintf(mess,"could not allocate chips\n"); + ret=FAIL; + } + if (myChan) + myModule.chanregs=myChan; + else { + sprintf(mess,"could not allocate chans\n"); + ret=FAIL; + } +#ifdef EIGERD + if (!myGain){ + sprintf(mess,"could not allocate gains\n"); + ret=FAIL; + } + if (!myOffset){ + sprintf(mess,"could not allocate offsets\n"); + ret=FAIL; + } +#endif + myModule.ndac=getNumberOfDACsPerModule(); + myModule.nchip=getNumberOfChipsPerModule(); + myModule.nchan=getNumberOfChannelsPerModule(); + myModule.nadc=getNumberOfADCsPerModule(); + +#endif + + + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + imod=arg; + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + ret=FAIL; + if (imod>=0) { + ret=OK; + myModule.module=imod; +#ifdef EIGERD + getModule(&myModule, myGain, myOffset); +#ifdef VERBOSE + for(i=0;i=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + } + +#ifdef VERBOSE + printf("Changing settings of module %d to %d\n", imod, isett); +#endif + + if (differentClients==1 && lockStatus==1 && isett!=GET_SETTINGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setSettings(isett, imod); +#ifdef VERBOSE + printf("Settings changed to %d\n", isett); +#endif + + if (retval==isett || isett<0) { + ret=OK; + } else { + ret=FAIL; + printf("Changing settings of module %d: wrote %d but read %d\n", imod, isett, retval); + } + + } +#endif + + if (ret==OK && differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + return ret; + + +} + + + + + + +int get_threshold_energy(int file_des) { + int retval; + int ret=OK,ret1=OK; + int n; + int imod; + + + n = receiveData(file_des,&imod,sizeof(imod),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#if defined(MYTHEND) || defined(EIGERD) +#ifdef VERBOSE + printf("Getting threshold energy of module %d\n", imod); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + } + + retval=getThresholdEnergy(imod); +#endif +#ifdef VERBOSE + printf("Threshold is %d eV\n", retval); +#endif +#endif + + if (differentClients==1 && ret==OK) + ret=FORCE_UPDATE; + + /* send answer */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + + /* Maybe this is done inside the initialization funcs */ + //detectorDacs[imod][ind]=val; + /*return ok/fail*/ + return ret; + +} + + + + +int set_threshold_energy(int file_des) { + int retval; + int ret=OK,ret1=OK; + int arg[3]; + int n; +#if defined(MYTHEND) || defined(EIGERD) + int ethr, imod; + enum detectorSettings isett; +#endif + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#if defined(MYTHEND) || defined(EIGERD) + ethr=arg[0]; + imod=arg[1]; + isett=arg[2]; +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number %d out of range\n",imod); + } + printf("Setting threshold energy of module %d to %d eV with settings %d\n", imod, ethr, isett); + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + retval=setThresholdEnergy(ethr, imod); + } +#ifdef VERBOSE + printf("Threshold set to %d eV\n", retval); +#endif + if (retval==ethr) + ret=OK; + else { + ret=FAIL; + printf("Setting threshold of module %d: wrote %d but read %d\n", imod, ethr, retval); + sprintf(mess,"Setting threshold of module %d: wrote %d but read %d\n", imod, ethr, retval); + } +#endif +#endif + if (ret==OK && differentClients==1) + ret=FORCE_UPDATE; + + /* send answer */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + + /* Maybe this is done inside the initialization funcs */ + //detectorDacs[imod][ind]=val; + /*return ok/fail*/ + return ret; + +} + + + + +int start_acquisition(int file_des) { + + int ret=OK,ret1=OK; + int n; + + + sprintf(mess,"can't start acquisition\n"); + +#ifdef VERBOSE + printf("Starting acquisition\n"); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + ret=startStateMachine(); + } +#endif + if (ret==FAIL) + sprintf(mess,"Start acquisition failed\n"); + else if (differentClients) + ret=FORCE_UPDATE; + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + return ret; + +} + +int stop_acquisition(int file_des) { + + int ret=OK,ret1=OK; + int n; + + + sprintf(mess,"can't stop acquisition\n"); + +//#ifdef VERBOSE + printf("Stopping acquisition\n"); +//#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + ret=stopStateMachine(); + } +#endif + if (ret==FAIL) + sprintf(mess,"Stop acquisition failed\n"); + else if (differentClients) + ret=FORCE_UPDATE; + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + return ret; + + +} + + + + +int start_readout(int file_des) { + + + int ret=OK,ret1=OK; + int n; + + + sprintf(mess,"can't start readout\n"); + +#ifdef VERBOSE + printf("Starting readout\n"); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + ret=startReadOut(); + } +#endif + if (ret==FAIL) + sprintf(mess,"Start readout failed\n"); + else if (differentClients) + ret=FORCE_UPDATE; + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + return ret; + + + +} + + + + +int get_run_status(int file_des) { + + int ret=OK,ret1=OK; + int n; + enum runStatus s; + sprintf(mess,"getting run status\n"); + +#ifdef VERBOSE + printf("Getting status\n"); +#endif +//#ifdef SLS_DETECTOR_FUNCTION_LIST + s= getRunStatus();printf("status:%x\n",s); +//#endif + + if (ret!=OK) { + printf("get status failed\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n += sendData(file_des,&s,sizeof(s),INT32); + } + return ret; +} + + + + + +int start_and_read_all(int file_des) { + int dataret1; +#ifdef VERBOSE + printf("Starting and reading all frames\n"); +#endif + + if (differentClients==1 && lockStatus==1) { + dataret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + //ret could be swapped during sendData + dataret1 = dataret; + sendData(file_des,&dataret1,sizeof(dataret),INT32); + sendData(file_des,mess,sizeof(mess),OTHER); + return dataret; + + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + startStateMachine(); + read_all(file_des); +#endif +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + + + return OK; + + +} + + + + +int read_frame(int file_des) { + + dataret=OK; + int dataret1; + if (differentClients==1 && lockStatus==1) { + dataret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + cprintf(RED,"%s",mess); + //dataret could be swapped during sendData + dataret1 = dataret; + sendData(file_des,&dataret1,sizeof(dataret1),INT32); + sendData(file_des,mess,sizeof(mess),OTHER); + printf("dataret %d\n",dataret); + return dataret; + } + +#ifdef SLS_DETECTOR_FUNCTION_LIST + dataretval=readFrame(&dataret, mess); +#endif + + + //dataret could be swapped during sendData + dataret1 = dataret; + sendData(file_des,&dataret1,sizeof(dataret1),INT32); + if (dataret==FAIL) + sendData(file_des,mess,sizeof(mess),OTHER);//sizeof(mess));//sizeof(mess)); + else if(dataret==OK){printf("shouldnt be sending anything but i am\n"); + sendData(file_des,dataretval,dataBytes,OTHER);} + + printf("dataret %d\n",dataret); + return dataret; +} + + + + + + + +int read_all(int file_des) { +#ifdef SLS_DETECTOR_FUNCTION_LIST + while(read_frame(file_des)==OK) { +#ifdef VERBOSE + printf("frame read\n"); +#endif + ; + } +#endif +#ifdef VERBOSE + printf("Frames finished\n"); +#endif + return OK; +} + + + + + + +int set_timer(int file_des) { + enum timerIndex ind; + int64_t tns; + int n; + int64_t retval; + int ret=OK,ret1=OK; + + + sprintf(mess,"can't set timer\n"); + + n = receiveData(file_des,&ind,sizeof(ind),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveData(file_des,&tns,sizeof(tns),INT64); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if (ret!=OK) { + printf(mess); + } + +#ifdef VERBOSE + printf("setting timer %d to %lld ns\n",ind,tns); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1 && tns!=-1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch(ind) { +#ifdef EIGERD + case SUBFRAME_ACQUISITION_TIME: + if (tns > ((int64_t)MAX_SUBFRAME_EXPOSURE_VAL_IN_10NS*10) ){ + ret=FAIL; + strcpy(mess,"Sub Frame exposure time should not exceed 5.368 seconds\n"); + break; + } + retval = setTimer(ind,tns); + break; +#endif +#ifdef MYTHEN + case PROBES_NUMBER: +#endif + case FRAME_NUMBER: + case ACQUISITION_TIME: + case FRAME_PERIOD: + case DELAY_AFTER_TRIGGER: + case GATES_NUMBER: + case CYCLES_NUMBER: + retval = setTimer(ind,tns); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown for this detector %d\n",ind); + break; + } + + } + } +#endif + if (ret!=OK) { + printf(mess); + printf("set timer failed\n"); + sprintf(mess, "set timer %d failed\n", ind); + } + else{ +#if defined(MYTHEND) || defined(GOTTHARD) + if (ind==FRAME_NUMBER) { + ret=allocateRAM(); + if (ret!=OK) + sprintf(mess, "could not allocate RAM for %lld frames\n", tns); + } +#endif + + if (differentClients) + ret=FORCE_UPDATE; +} + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { +#ifdef VERBOSE + printf("returning ok %d\n",sizeof(retval)); +#endif + + n = sendData(file_des,&retval,sizeof(retval),INT64); + } + + return ret; + +} + + + + + + + + +int get_time_left(int file_des) { + + enum timerIndex ind; + int n; + int64_t retval; + int ret=OK,ret1=OK; + + sprintf(mess,"can't get timer\n"); + n = receiveData(file_des,&ind,sizeof(ind),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("getting time left on timer %d \n",ind); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + switch(ind) { + case PROBES_NUMBER: +#ifndef MYTHEND + ret=FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); + break; +#endif + case FRAME_NUMBER: + case ACQUISITION_TIME: + case FRAME_PERIOD: + case DELAY_AFTER_TRIGGER: + case GATES_NUMBER: + case CYCLES_NUMBER: + case PROGRESS: + case ACTUAL_TIME: + case MEASUREMENT_TIME: + getTimeLeft(ind); + break; + default: + ret=FAIL; + sprintf(mess,"timer index unknown %d\n",ind); + break; + } + } +#endif + + if (ret!=OK) { + printf("get time left failed\n"); + } else if (differentClients) + ret=FORCE_UPDATE; + +#ifdef VERBOSE + printf("time left on timer %d is %lld\n",ind, retval); +#endif + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&retval,sizeof(retval),INT64); + } +#ifdef VERBOSE + printf("data sent\n"); +#endif + return ret; +} + + + + + +int set_dynamic_range(int file_des) { + + int dr; + int n; + int retval; + int ret=OK,ret1=OK; + int rateret=OK,rateret1=OK; + + sprintf(mess,"can't set dynamic range\n"); + + n = receiveData(file_des,&dr,sizeof(dr),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1 && dr>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef EIGERD + switch(dr){ + case -1:case 4: case 8: case 16:case 32:break; + default: + strcpy(mess,"could not set dynamic range. Must be 4,8,16 or 32.\n"); + ret = FAIL; + } +#endif + } + if(ret == OK){ + retval=setDynamicRange(dr); + if (dr>=0 && retval!=dr) + ret=FAIL; + //look at rate correction only if dr change worked + if((ret==OK) && (dr!=32) && (dr!=-1) && (getRateCorrectionEnable())){ + setRateCorrection(0); + strcpy(mess,"Switching off Rate Correction. Must be in 32 bit mode\n"); + cprintf(RED,"%s",mess); + rateret = FAIL; + } + } +#endif + if (dr>=0 && retval!=dr) + ret=FAIL; + if ((ret==OK) && (differentClients)) + ret=FORCE_UPDATE; + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (dr>=0) dataBytes=calculateDataBytes(); +#endif + + //rate correction ret + //ret could be swapped during sendData + rateret1 = rateret; + n = sendData(file_des,&rateret1,sizeof(rateret),INT32); + if (rateret==FAIL) + n = sendData(file_des,mess,sizeof(mess),OTHER); + + //dynamic range ret + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n = sendData(file_des,mess,sizeof(mess),OTHER); + else + n = sendData(file_des,&retval,sizeof(retval),INT32); + return ret; +} + + + + + + +int set_readout_flags(int file_des) { + + enum readOutFlags retval; + enum readOutFlags arg; + int n; + int ret=OK,ret1=OK; + + sprintf(mess,"can't set readout flags\n"); + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + + +#if !defined(MYTHEND) && !defined(EIGERD) + sprintf(mess,"Read out flags not implemented for this detector\n"); + cprintf(RED, "%s",mess); + ret=FAIL; +#else + + +#ifdef VERBOSE + printf("setting readout flags to %d\n",arg); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + switch(arg) { + case GET_READOUT_FLAGS: +#ifdef MYTHEND + case TOT_MODE: + case NORMAL_READOUT: +#endif +#if defined(MYTHEND) || defined(EIGERD) + case STORE_IN_RAM: + case CONTINOUS_RO: +#endif +#ifdef EIGERD + case PARALLEL: + case NONPARALLEL: + case SAFE: +#endif + retval=setReadOutFlags(arg); + break; + + default: + sprintf(mess,"Unknown readout flag %d for this detector\n", arg); + cprintf(RED, "%s",mess); + ret=FAIL; + break; + } + } +#endif + +#endif + + if (ret==OK) { + if ((retval == -1) || ((arg!=-1)&&((retval&arg)!=arg))){ + cprintf(RED,"arg:0x%x, retval:0x%x retval&arg:0x%x\n",(int)arg,(int)retval,retval&arg); + ret=FAIL; + sprintf(mess,"Could not change readout flag: should be 0x%x but is 0x%x\n", arg, retval); + cprintf(RED, "%s",mess); + }else if (differentClients) + ret=FORCE_UPDATE; + } + + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&retval,sizeof(retval),INT32); + } + return ret; +} + + + + + +int set_roi(int file_des) { + + int ret=OK,ret1=OK; + ROI arg[MAX_ROIS]; + ROI* retval=0; + int nroi=-1, n=0, retvalsize=0,retvalsize1,i; + strcpy(mess,"Could not set/get roi\n"); + + n = receiveData(file_des,&nroi,sizeof(nroi),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + if(nroi!=-1){ + for(i=0;i=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef SLS_DETECTOR_FUNCTION_LIST + switch (arg) { +#ifdef MYTHEND + case CLOCK_DIVIDER: + case WAIT_STATES: + case SET_SIGNAL_LENGTH: + case TOT_CLOCK_DIVIDER: + case TOT_DUTY_CYCLE: + retval=setSpeed(arg, val); + break; +#elif EIGERD + case CLOCK_DIVIDER: + retval=setSpeed(arg, val); + break; +#endif + default: + sprintf(mess,"unknown speed variable %d for this detector\n",arg); + ret=FAIL; + break; + } +#endif + } + if (ret==OK){ + if ((retval!=val) && (val>=0)) { + ret=FAIL; + sprintf(mess,"could not change speed variable %d: should be %d but is %d \n",arg, val, retval); + }else if (differentClients) + ret=FORCE_UPDATE; + + } + } + + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&retval,sizeof(retval),INT32); + } + return ret; +} + + + + +int execute_trimming(int file_des) { + + int arg[3]; + int n; + int ret=OK, ret1=OK, retval=0; +#if defined(MYTHEND) || defined(EIGERD) + int imod, par1,par2; +#endif + enum trimMode mode; + + printf("called function execute trimming\n"); + + sprintf(mess,"can't set execute trimming\n"); + + n = receiveData(file_des,&mode,sizeof(mode),INT32); + printf("mode received\n"); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (mode)\n"); + ret=FAIL; + } + + n = receiveData(file_des,arg,sizeof(arg),INT32); + printf("arg received\n"); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + printf("Error reading from socket (args)\n"); + ret=FAIL; + } + +#if !defined(MYTHEND) && !defined(EIGERD) + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else + + imod=arg[0]; + par1=arg[1]; + par2=arg[2]; +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number out of range %d\n",imod); + } +#endif + if (ret==OK) { + +#ifdef VERBOSE + printf("trimming module %d mode %d, parameters %d %d \n",imod,mode, par1, par2); +#endif + + if (differentClients==1 && lockStatus==1 ) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + switch(mode) { + case NOISE_TRIMMING: + case BEAM_TRIMMING: + case IMPROVE_TRIMMING: + case FIXEDSETTINGS_TRIMMING: + if (myDetectorType==MYTHEN) { + retval=executeTrimming(mode, par1, par2, imod); + break; + } + break; + default: + printf("Unknown trimming mode %d\n",mode); + sprintf(mess,"Unknown trimming mode %d\n",mode); + ret=FAIL; + break; + } + } +#endif + } + } +#endif + + if (ret!=OK) { + sprintf(mess,"can't set execute trimming\n"); + ret=FAIL; + } else if (retval>0) { + sprintf(mess,"Could not trim %d channels\n", retval); + ret=FAIL; + } else if (differentClients) + ret=FORCE_UPDATE; + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } + + return ret; +} + + + + + + + + + +int configure_mac(int file_des) { + + int retval=-100; + int ret=OK,ret1=OK; + char arg[6][50]; + int n; + +#ifndef MYTHEND + int imod=0;//should be in future sent from client as -1, arg[2] + int ipad; + long long int imacadd; + long long int idetectormacadd; + int udpport; + int udpport2; + int detipad; +#endif + + sprintf(mess,"Can't configure MAC\n"); + + n = receiveData(file_des,arg,sizeof(arg),OTHER); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef MYTHEND + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else + sscanf(arg[0], "%x", &ipad); + sscanf(arg[1], "%llx", &imacadd); + sscanf(arg[2], "%x", &udpport); + sscanf(arg[3], "%llx", &idetectormacadd); + sscanf(arg[4], "%x", &detipad); + sscanf(arg[5], "%x", &udpport2); + + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (imod>=getTotalNumberOfModules()) { + ret=FAIL; + sprintf(mess,"Module number out of range %d\n",imod); + printf("mess:%s\n",mess); + } +#endif +#ifdef VERBOSE + int i; + /*printf("\ndigital_test_bit in server %d\t",digitalTestBit);for gotthard*/ + printf("\nipadd %x\t",ipad); + printf("destination ip is %d.%d.%d.%d = 0x%x \n",(ipad>>24)&0xff,(ipad>>16)&0xff,(ipad>>8)&0xff,(ipad)&0xff,ipad); + printf("macad:%llx\n",imacadd); + for (i=0;i<6;i++) + printf("mac adress %d is 0x%x \n",6-i,(unsigned int)(((imacadd>>(8*i))&0xFF))); + printf("udp port:0x%x\n",udpport); + printf("detector macad:%llx\n",idetectormacadd); + for (i=0;i<6;i++) + printf("detector mac adress %d is 0x%x \n",6-i,(unsigned int)(((idetectormacadd>>(8*i))&0xFF))); + printf("detipad %x\n",detipad); + printf("udp port2:0x%x\n",udpport2); + printf("\n"); + printf("Configuring MAC of module %d at port %x\n", imod, udpport); +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if(getRunStatus() == RUNNING){ + stopStateMachine(); + } + + retval=configureMAC(ipad,imacadd,idetectormacadd,detipad,udpport,udpport2,0); /*digitalTestBit);*/ + if(retval==-1) ret=FAIL; + } +#endif +#ifdef VERBOSE + printf("Configured MAC with retval %d\n", retval); +#endif + if (ret==FAIL) { + printf("configuring MAC of mod %d failed\n", imod); + } + + if (differentClients) + ret=FORCE_UPDATE; +#endif + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; + +} + + + +int load_image(int file_des) { + int retval; + int ret=OK,ret1=OK; + int n; + enum imageType index; + char ImageVals[dataBytes]; + + sprintf(mess,"Loading image failed\n"); + + n = receiveData(file_des,&index,sizeof(index),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + + n = receiveData(file_des,ImageVals,dataBytes,OTHER); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifndef GOTTHARDD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } + +#ifdef SLS_DETECTOR_FUNCTION_LIST + switch (index) { + case DARK_IMAGE : +#ifdef VERBOSE + printf("Loading Dark image\n"); +#endif + case GAIN_IMAGE : +#ifdef VERBOSE + printf("Loading Gain image\n"); +#endif + if (myDetectorType==GOTTHARD) { + retval=loadImage(index,ImageVals); + if (retval==-1) + ret = FAIL; + } + break; + default: + printf("Unknown index %d\n",index); + sprintf(mess,"Unknown index %d\n",index); + ret=FAIL; + break; + } +#endif + } +#endif + + + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; +} + + + + + +int read_counter_block(int file_des) { + + int ret=OK,ret1=OK; + int n; + int startACQ; + //char *retval=NULL; +#ifdef GOTTHARDD + char CounterVals[NCHAN*NCHIP]; +#else + char CounterVals[dataBytes]; +#endif + + sprintf(mess,"Read counter block failed\n"); + + n = receiveData(file_des,&startACQ,sizeof(startACQ),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifndef GOTTHARDD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else{ + ret=readCounterBlock(startACQ,CounterVals); +#ifdef VERBOSE + int i; + for(i=0;i<6;i++) + printf("%d:%d\t",i,CounterVals[i]); +#endif + } + } +#endif +#endif + + if(ret!=FAIL){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret!=FAIL) { + /* send return argument */ + n += sendData(file_des,CounterVals,dataBytes,OTHER);//1280*2 + } else { + n += sendData(file_des,mess,sizeof(mess),OTHER); + } + + /*return ok/fail*/ + return ret; +} + + + + + +int reset_counter_block(int file_des) { + + int ret=OK,ret1=OK; + int n; + int startACQ; + + sprintf(mess,"Reset counter block failed\n"); + + n = receiveData(file_des,&startACQ,sizeof(startACQ),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifndef GOTTHARDD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=resetCounterBlock(startACQ); + } +#endif +#endif + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + + /*return ok/fail*/ + return ret; +} + + + + + + + + +int start_receiver(int file_des) { + int ret=OK,ret1=OK; + int n=0; + strcpy(mess,"Could not start receiver\n"); + + /* execute action if the arguments correctly arri ved*/ +#if defined(GOTTHARDD) || defined(EIGERD) +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret = startReceiver(1); + +#endif +#else + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#endif + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if(ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + /*return ok/fail*/ + return ret; +} + + + + + + +int stop_receiver(int file_des) { + int ret=OK,ret1=OK; + int n=0; + + strcpy(mess,"Could not stop receiver\n"); + + /* execute action if the arguments correctly arrived*/ +#ifndef GOTTHARDD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (lockStatus==1 && differentClients==1){//necessary??? + sprintf(mess,"Detector locked by %s\n", lastClientIP); + ret=FAIL; + } + else + ret=startReceiver(0); + +#endif +#endif + + if(ret==OK && differentClients){ + printf("Force update\n"); + ret=FORCE_UPDATE; + } + + /* send answer */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if(ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + /*return ok/fail*/ + return ret; +} + + + + + +int calibrate_pedestal(int file_des){ + + int ret=OK,ret1=OK; + int retval=-1; + int n; + int frames; + + sprintf(mess,"Could not calibrate pedestal\n"); + + n = receiveData(file_des,&frames,sizeof(frames),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifndef GOTTHARDD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=calibratePedestal(frames); + } +#endif +#endif + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + else + n += sendData(file_des,&retval,sizeof(retval),INT32); + + /*return ok/fail*/ + return ret; +} + + + + + + + + + +int enable_ten_giga(int file_des) { + int n; + int retval=-1; + int ret=OK,ret1=OK; + int arg = -1; + + sprintf(mess,"Can't enable/disable 10Gbe \n"); + /* receive arguments */ + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + /* execute action */ +#ifndef EIGERD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef VERBOSE + printf("Enabling 10Gbe :%d \n",arg); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if(ret != FAIL){ + + retval=enableTenGigabitEthernet(arg); + if((arg != -1) && (retval != arg)) + ret=FAIL; + else if (differentClients==1) { + ret=FORCE_UPDATE; + } + } +#endif +#endif + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + /*return ok/fail*/ + return ret; +} + + + +int set_all_trimbits(int file_des){ + + + int retval; + int arg; + int n; + int ret=OK,ret1=OK; + + sprintf(mess,"can't set sll trimbits\n"); + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifndef EIGERD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef VERBOSE + printf("setting all trimbits to %d\n",arg); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (differentClients==1 && lockStatus==1 && arg!=GET_READOUT_FLAGS) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + if(arg < -1){ + ret = FAIL; + strcpy(mess,"Cant set trimbits to this value\n"); + }else { + if(arg >= 0) + setAllTrimbits(arg); + retval = getAllTrimbits(); + } + } +#endif + if (ret==OK) { + if (arg!=-1 && arg!=retval) { + ret=FAIL; + sprintf(mess,"Could not set all trimbits: should be %d but is %d\n", arg, retval); + }else if (differentClients) + ret=FORCE_UPDATE; + } +#endif + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&retval,sizeof(retval),INT32); + } + return ret; + +} + + + + + +int set_counter_bit(int file_des) { + int n; + int retval = -1; + int ret=OK,ret1=OK; + int arg = -1; + + sprintf(mess,"Can't set/rest counter bit \n"); + /* receive arguments */ + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + /* execute action */ +#ifndef EIGERD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef VERBOSE + printf("Getting/Setting/Resetting counter bit :%d \n",arg); +#endif +#ifdef SLS_DETECTOR_FUNCTION_LIST + if(ret != FAIL){ + retval=setCounterBit(arg); + if((arg != -1) && (retval != arg)) + ret=FAIL; + else if (differentClients==1) { + ret=FORCE_UPDATE; + } + } +#endif +#endif + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + /* send return argument */ + n += sendData(file_des,&retval,sizeof(retval),INT32); + /*return ok/fail*/ + return ret; +} + + +int pulse_pixel(int file_des) { + + int ret=OK,ret1=OK; + int n; + int arg[3]; + arg[0]=-1; arg[1]=-1; arg[2]=-1; + + + sprintf(mess,"pulse pixel failed\n"); + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifndef EIGERD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=pulsePixel(arg[0],arg[1],arg[2]); + } +#endif +#endif + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + + /*return ok/fail*/ + return ret; +} + + +int pulse_pixel_and_move(int file_des) { + + int ret=OK,ret1=OK; + int n; + int arg[3]; + arg[0]=-1; arg[1]=-1; arg[2]=-1; + + + sprintf(mess,"pulse pixel and move failed\n"); + + n = receiveData(file_des,arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifndef EIGERD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=pulsePixelNMove(arg[0],arg[1],arg[2]); + } +#endif +#endif + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + + /*return ok/fail*/ + return ret; + +} + + + + +int pulse_chip(int file_des) { + + int ret=OK,ret1=OK; + int n; + int arg = -1; + + + sprintf(mess,"pulse chip failed\n"); + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } +#ifndef EIGERD + ret = FAIL; + strcpy(mess,"Not applicable/implemented for this detector\n"); +#else +#ifdef SLS_DETECTOR_FUNCTION_LIST + if (ret==OK) { + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else + ret=pulseChip(arg); + } +#endif +#endif + if(ret==OK){ + if (differentClients) + ret=FORCE_UPDATE; + } + + /* send answer */ + /* send OK/failed */ + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n += sendData(file_des,mess,sizeof(mess),OTHER); + + /*return ok/fail*/ + return ret; + +} + + + + +int set_rate_correct(int file_des) { + int64_t tau_ns=-1; + int n; + int ret=OK,ret1=OK; + + sprintf(mess,"can't set/unset rate correction\n"); + + n = receiveData(file_des,&tau_ns,sizeof(tau_ns),INT64); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + cprintf(RED,"%s",mess); + ret=FAIL; + } + +#ifndef EIGERD + sprintf(mess,"Rate Correction not implemented for this detector\n"); + cprintf(RED,"%s",mess); + ret=FAIL; +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + + if (ret==OK) { + printf("Setting rate correction to %lld ns\n",tau_ns); + + if (differentClients==1 && lockStatus==1) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { + + //tau = -1, use default tau of settings + if((ret==OK)&&(tau_ns<0)){ + tau_ns = getDefaultSettingsTau_in_nsec(); + } + //still negative (not set) + if(tau_ns < 0){ + ret = FAIL; + if(getRateCorrectionEnable()){ + setRateCorrection(0); + strcpy(mess,"Cannot set rate correction as default tau not provided. Switching off Rate Correction\n"); + }else{ + strcpy(mess,"Cannot set rate correction as default tau not provided\n"); + } + cprintf(RED,"%s",mess); + } + + //set rate + else{ + //not 32 bit mode + if((setDynamicRange(-1)!=32) && (tau_ns!=0)){ + strcpy(mess,"Rate correction Deactivated, must be in 32 bit mode\n"); + cprintf(RED,"%s",mess); + ret=FAIL; + } + //32 bit mode + else{ + int64_t retval = setRateCorrection(tau_ns); //tau_ns will not be -1 here + if(tau_ns != retval){ + cprintf(RED,"%s",mess); + ret=FAIL; + } + } + } + } + } +#endif + if ((ret==OK) && (differentClients)) + ret=FORCE_UPDATE; + + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } + + return ret; +} + + + + +int get_rate_correct(int file_des) { + int64_t retval=-1; + int ret=OK,ret1=OK; + + sprintf(mess,"can't get rate correction\n"); + + +#ifndef EIGERD + sprintf(mess,"Rate Correction not implemented for this detector\n"); + cprintf(RED,"%s",mess); + ret=FAIL; +#endif + +#ifdef SLS_DETECTOR_FUNCTION_LIST + + if (ret==OK) { + retval = getCurrentTau(); + printf("Getting rate correction %lld\n",(long long int)retval); + } +#endif + if ((ret==OK) && (differentClients)) + ret=FORCE_UPDATE; + + + //ret could be swapped during sendData + ret1 = ret; + sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + sendData(file_des,mess,sizeof(mess),OTHER); + } else { + sendData(file_des,&retval,sizeof(retval),INT64); + } + + return ret; +} + + + + + + +int set_activate(int file_des) { + + int arg, n; + int ret=OK,ret1=OK; + int retval; + + sprintf(mess,"can't activate/deactivate detector\n"); + + n = receiveData(file_des,&arg,sizeof(arg),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("Setting activate mode of detector to %d\n",arg); +#endif + if (ret==OK) { + + if (differentClients==1 && lockStatus==1 && arg>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef SLS_DETECTOR_FUNCTION_LIST +#ifdef EIGERD + retval=activate(arg); +#else + sprintf(mess,"Deactivate/Activate Not implemented for this detector\n"); + ret=FAIL; +#endif +#endif + } + if (ret==OK){ + if ((retval!=arg) && (arg!=-1)) { + ret=FAIL; + sprintf(mess,"Could not set activate mode to %d, is set to %d\n",arg, retval); + }else if (differentClients) + ret=FORCE_UPDATE; + + } + } + + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) { + n = sendData(file_des,mess,sizeof(mess),OTHER); + } else { + n = sendData(file_des,&retval,sizeof(retval),INT32); + } + return ret; +} + + + + + + + + +int set_network_parameter(int file_des) { + + enum detNetworkParameter index; + enum networkParameter mode; + int value = -1; + int ret=OK,ret1=OK; + int retval = -1,n; + + sprintf(mess,"can't set network parameter\n"); + n = receiveData(file_des,&mode,sizeof(mode),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + n = receiveData(file_des,&value,sizeof(value),INT32); + if (n < 0) { + sprintf(mess,"Error reading from socket\n"); + ret=FAIL; + } + +#ifdef VERBOSE + printf("setting network parameter mode %d to %d\n",(int)mode,value); +#endif + if (ret==OK) { + if (differentClients==1 && lockStatus==1 && value>=0) { + ret=FAIL; + sprintf(mess,"Detector locked by %s\n",lastClientIP); + } else { +#ifdef SLS_DETECTOR_FUNCTION_LIST + switch (mode) { +#ifdef EIGERD + case DETECTOR_TXN_DELAY_LEFT: + index = TXN_LEFT; + break; + case DETECTOR_TXN_DELAY_RIGHT: + index = TXN_RIGHT; + break; + case DETECTOR_TXN_DELAY_FRAME: + index = TXN_FRAME; + break; + case FLOW_CONTROL_10G: + index = FLOWCTRL_10G; + break; +#endif + default: + sprintf(mess,"unknown network parameter %d for this detector\n",mode); + ret=FAIL; + break; + } + if (ret==OK) + retval=setNetworkParameter(index, value); +#endif + } + if (ret==OK){ + if ((retval!=value) && (value>=0)) { + ret=FAIL; + sprintf(mess,"could not change network parameter mode %d: should be %d but is %d \n",index, value, retval); + cprintf(RED, "%s",mess); + }else if (differentClients) + ret=FORCE_UPDATE; + } + } + + //ret could be swapped during sendData + ret1 = ret; + n = sendData(file_des,&ret1,sizeof(ret),INT32); + if (ret==FAIL) + n = sendData(file_des,mess,sizeof(mess),OTHER); + else + n = sendData(file_des,&retval,sizeof(retval),INT32); + + return ret; +} diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h new file mode 100755 index 000000000..5eebc1050 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/slsDetectorServer_funcs.h @@ -0,0 +1,95 @@ +#ifndef SERVER_FUNCS_H +#define SERVER_FUNCS_H + +#include "sls_detector_defs.h" +#include "slsDetectorServer_defs.h" + +#include + + + + + +//basic server functions +void checkFirmwareCompatibility(); +int init_detector(int); +int decode_function(int); +int function_table(); +//int swap_int32(int val); +//int64_t swap_int64(int64_t val); +int M_nofunc(int); +int exit_server(int); +int exec_command(int); + +//advnaced server functions +int lock_server(int); +int get_last_client_ip(int); +int set_port(int); +int send_update(int); +int update_client(int); +int set_master(int); +int set_synchronization(int); + +//detector specific functions +//F_GET_ERROR +int get_detector_type(int); +int set_number_of_modules(int); +int get_max_number_of_modules(int); +int set_external_signal_flag(int); +int set_external_communication_mode(int); +int get_id(int); +int digital_test(int); +//F_ANALOG_TEST +//F_ENABLE_ANALOG_OUT +//F_CALIBRATION_PULSE +int set_dac(int); +int get_adc(int); +int write_register(int); +int read_register(int); +//F_WRITE_MEMORY +//F_READ_MEMORY +int set_channel(int); +int get_channel(int); +//F_SET_ALL_CHANNELS +int set_chip(int); +int get_chip(int); +//F_SET_ALL_CHIPS +int set_module(int); +int get_module(int); +//F_SET_ALL_MODULES +int set_settings(int); +int get_threshold_energy(int); +int set_threshold_energy(int); +int start_acquisition(int); +int stop_acquisition(int); +int start_readout(int); +int get_run_status(int); +int start_and_read_all(int); +int read_frame(int); +int read_all(int); +int set_timer(int); +int get_time_left(int); +int set_dynamic_range(int); +int set_readout_flags(int); +int set_roi(int); +int set_speed(int); +int execute_trimming(int); +int configure_mac(int); +int load_image(int); +int read_counter_block(int); +int reset_counter_block(int); +int start_receiver(int); +int stop_receiver(int); +int calibrate_pedestal(int); +int enable_ten_giga(int); +int set_all_trimbits(int); +int set_counter_bit(int); +int pulse_pixel(int); +int pulse_pixel_and_move(int); +int pulse_chip(int); +int set_rate_correct(int); +int get_rate_correct(int); +int set_activate(int); +int set_network_parameter(int); + +#endif diff --git a/slsDetectorSoftware/slsDetectorServer/slsDetector_stopServer.c b/slsDetectorSoftware/slsDetectorServer/slsDetector_stopServer.c new file mode 100755 index 000000000..1772ce2b6 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/slsDetector_stopServer.c @@ -0,0 +1,46 @@ +/* A simple server in the internet domain using TCP + The port number is passed as an argument */ +#include "communication_funcs.h" + +#include "slsDetectorFunctionList.h"/*#include "slsDetector_firmware.h" for the time being*/ +#include "slsDetectorServer_defs.h" + +#include +#include + +int sockfd; + +int main(int argc, char *argv[]) +{ + int portno; + int retval=0; + int sd,fd; + + portno = DEFAULT_PORTNO; + + + sd=bindSocket(portno); //defined in communication_funcs + if (getServerError(sd)) //defined in communication_funcs + return -1; + + + + /* waits for connection */ + while(retval!=GOODBYE) { +#ifdef VERBOSE + printf("\n"); +#endif +#ifdef VERY_VERBOSE + printf("Stop server: waiting for client call\n"); +#endif + fd=acceptConnection(sd); //defined in communication_funcs + retval=stopStateMachine();//defined in slsDetectorFirmare_funcs + closeConnection(fd); //defined in communication_funcs + } + + exitServer(sd); //defined in communication_funcs + printf("Goodbye!\n"); + + return 0; +} + diff --git a/slsDetectorSoftware/slsDetectorServer/sls_detector_defs.h b/slsDetectorSoftware/slsDetectorServer/sls_detector_defs.h new file mode 120000 index 000000000..c5062e03f --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/sls_detector_defs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_defs.h \ No newline at end of file diff --git a/slsDetectorSoftware/slsDetectorServer/sls_detector_funcs.h b/slsDetectorSoftware/slsDetectorServer/sls_detector_funcs.h new file mode 120000 index 000000000..844b67129 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorServer/sls_detector_funcs.h @@ -0,0 +1 @@ +../commonFiles/sls_detector_funcs.h \ No newline at end of file diff --git a/slsDetectorSoftware/slsDetectorUsers.doxy b/slsDetectorSoftware/slsDetectorUsers.doxy new file mode 100644 index 000000000..6f3674742 --- /dev/null +++ b/slsDetectorSoftware/slsDetectorUsers.doxy @@ -0,0 +1,86 @@ +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + + + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = YES + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +INTERNAL_DOCS = NO + +SHOW_INCLUDE_FILES = NO + +SHOW_FILES = NO + +SHOW_NAMESPACES = NO + +COMPACT_LATEX = YES + +PAPER_TYPE = a4 + +PDF_HYPERLINKS = YES + +USE_PDFLATEX = YES + +LATEX_HIDE_INDICES = YES + + +PREDEFINED = __cplusplus + +INPUT = slsDetector/slsDetectorUsers.h slsDetectorAnalysis/detectorData.h + +OUTPUT_DIRECTORY = slsDetectorUsersDocs diff --git a/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp new file mode 100644 index 000000000..e5a5011a0 --- /dev/null +++ b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.cpp @@ -0,0 +1,168 @@ +#include "receiverInterface.h" + + +#include +#include +#include +#include +#include +#include +#include + + + +receiverInterface::receiverInterface(MySocketTCP *socket):dataSocket(socket){} + + + +receiverInterface::~receiverInterface(){ + delete dataSocket; +} + + + +int receiverInterface::sendString(int fnum, char retval[], char arg[]){ + int ret = slsDetectorDefs::FAIL; + char mess[100] = ""; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->SendDataOnly(arg,MAX_STR_LENGTH); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==slsDetectorDefs::FAIL){ + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + dataSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH); + + return ret; +} + + + +int receiverInterface::sendUDPDetails(int fnum, char retval[], char arg[3][MAX_STR_LENGTH]){ + char args[3][MAX_STR_LENGTH]; + int ret = slsDetectorDefs::FAIL; + char mess[100] = ""; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->SendDataOnly(arg,sizeof(args)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==slsDetectorDefs::FAIL){ + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + else + dataSocket->ReceiveDataOnly(retval,MAX_STR_LENGTH); + + return ret; +} + + +int receiverInterface::sendInt(int fnum, int &retval, int arg){ + int ret = slsDetectorDefs::FAIL; + char mess[100] = ""; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->SendDataOnly(&arg,sizeof(arg)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==slsDetectorDefs::FAIL){ + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + + return ret; +} + + + +int receiverInterface::getInt(int fnum, int &retval){ + int ret = slsDetectorDefs::FAIL; + char mess[100] = ""; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==slsDetectorDefs::FAIL){ + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + + return ret; +} + + + +int receiverInterface::sendInt(int fnum, int64_t &retval, int64_t arg){ + int ret = slsDetectorDefs::FAIL; + char mess[100] = ""; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->SendDataOnly(&arg,sizeof(arg)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==slsDetectorDefs::FAIL){ + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + + return ret; +} + + + +int receiverInterface::sendIntArray(int fnum, int64_t &retval, int64_t arg[2]){ + int64_t args[2]; + int ret = slsDetectorDefs::FAIL; + char mess[100] = ""; + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->SendDataOnly(arg,sizeof(args)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==slsDetectorDefs::FAIL){ + dataSocket->ReceiveDataOnly(mess,sizeof(mess)); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + + return ret; +} + + + +int receiverInterface::getInt(int fnum, int64_t &retval){ + int ret = slsDetectorDefs::FAIL; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + dataSocket->ReceiveDataOnly(&retval,sizeof(retval)); + + return ret; +} + + +int receiverInterface::getLastClientIP(int fnum, char retval[]){ + int ret = slsDetectorDefs::FAIL; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + dataSocket->ReceiveDataOnly(retval,sizeof(retval)); + + return ret; +} + + + +int receiverInterface::executeFunction(int fnum,char mess[]){ + int ret = slsDetectorDefs::FAIL; + + dataSocket->SendDataOnly(&fnum,sizeof(fnum)); + dataSocket->ReceiveDataOnly(&ret,sizeof(ret)); + if (ret==slsDetectorDefs::FAIL){ + dataSocket->ReceiveDataOnly(mess,MAX_STR_LENGTH); + std::cout<< "Receiver returned error: " << mess << std::endl; + } + + return ret; +} + + diff --git a/slsDetectorSoftware/slsReceiverInterface/receiverInterface.h b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.h new file mode 100644 index 000000000..27fbea6a1 --- /dev/null +++ b/slsDetectorSoftware/slsReceiverInterface/receiverInterface.h @@ -0,0 +1,134 @@ + + + +#ifndef SLS_RECEIVER_INTERFACE_H +#define SLS_RECEIVER_INTERFACE_H + +#include "sls_detector_defs.h" +#include "MySocketTCP.h" + + + +/** + * + * @short the slsReceiverInterface class is the interface between the sls detector and the sls receiver + * @author Dhanya Maliakal + * @version 0.1alpha + */ + + +class receiverInterface{ + +public: + + /** + * (default) constructor + * @param socket tcp socket between client and receiver + */ + receiverInterface(MySocketTCP *socket); + + + /** + * destructor + */ + virtual ~receiverInterface(); + + /** + * Set the datasocket + * @param socket the data socket + */ + void setSocket(MySocketTCP *socket){dataSocket=socket;}; + + + /** + * Send a string to receiver + * @param fnum function enum to determine what parameter + * @param retval return value + * @param arg value to send + * \returns success of operation + */ + int sendString(int fnum, char retval[], char arg[]); + + /** + * Send a string to receiver + * @param fnum function enum to send udp ip and udp port + * @param retval return value receiver mac + * @param arg value to send + * \returns success of operation + */ + int sendUDPDetails(int fnum, char retval[], char arg[3][MAX_STR_LENGTH]); + + + /** + * Send an integer to receiver + * @param fnum function enum to determine what parameter + * @param retval return value + * @param arg value to send + * \returns success of operation + */ + int sendInt(int fnum, int &retval, int arg); + + /** + * Get an integer value from receiver + * @param fnum function enum to determine what parameter + * @param retval return value + * \returns success of operation + */ + int getInt(int fnum, int &retval); + + /** + * Send an integer to receiver + * @param fnum function enum to determine what parameter + * @param retval return value + * @param arg value to send + * \returns success of operation + */ + int sendInt(int fnum, int64_t &retval, int64_t arg); + + + /** + * Send an integer to receiver + * @param fnum function enum to determine what parameter + * @param retval return value + * @param arg values to send + * \returns success of operation + */ + int sendIntArray(int fnum, int64_t &retval, int64_t arg[2]); + + /** + * Get an integer value from receiver + * @param fnum function enum to determine what parameter + * @param retval return value + * \returns success of operation + */ + int getInt(int fnum, int64_t &retval); + + /** + * Get last client ip connected to receiver + * @param fnum function enum to get last client up + * @param retval return value + * \returns success of operation + */ + int getLastClientIP(int fnum, char retval[]); + + + /** + * Send a function number to execute function + * @param fnum function enum to determine which function to execute + * @param mess return error message + * \returns success of operation + */ + int executeFunction(int fnum,char mess[]); + + //here one should implement the funcs listed in + +private: + + /** + * socket for data acquisition + */ + MySocketTCP *dataSocket; + +}; + +#endif diff --git a/slsDetectorSoftware/threadFiles/CondVar.cpp b/slsDetectorSoftware/threadFiles/CondVar.cpp new file mode 100644 index 000000000..2feff962f --- /dev/null +++ b/slsDetectorSoftware/threadFiles/CondVar.cpp @@ -0,0 +1,17 @@ +#include "CondVar.h" + +CondVar::CondVar() { + pthread_cond_init(&m_cond_var, NULL); +} +CondVar::~CondVar() { + pthread_cond_destroy(&m_cond_var); +} +void CondVar::wait(pthread_mutex_t* mutex) { + pthread_cond_wait(&m_cond_var, mutex); +} +void CondVar::signal() { + pthread_cond_signal(&m_cond_var); +} +void CondVar::broadcast() { + pthread_cond_broadcast(&m_cond_var); +} diff --git a/slsDetectorSoftware/threadFiles/CondVar.h b/slsDetectorSoftware/threadFiles/CondVar.h new file mode 100644 index 000000000..b823ef31d --- /dev/null +++ b/slsDetectorSoftware/threadFiles/CondVar.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include +#include +#include + +#include "Global.h" + +using namespace std; + +class CondVar { +public: + + CondVar(); + ~CondVar(); + void wait(pthread_mutex_t* mutex); + void signal(); + void broadcast(); + +private: + pthread_cond_t m_cond_var; +}; diff --git a/slsDetectorSoftware/threadFiles/Global.h b/slsDetectorSoftware/threadFiles/Global.h new file mode 100644 index 000000000..2596df0c0 --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Global.h @@ -0,0 +1,6 @@ +#pragma once + +const int DEFAULT_POOL_SIZE = 10; +const int MAX_SINGLES = 5; +const int STARTED = 0; +const int STOPPED = 1; diff --git a/slsDetectorSoftware/threadFiles/Makefile b/slsDetectorSoftware/threadFiles/Makefile new file mode 100644 index 000000000..19b5b40e4 --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Makefile @@ -0,0 +1,21 @@ +OBJPATH=bin/obj +EXAMPLEPATH=bin/example + +all: + g++ CondVar.cpp -lpthread -c -g -o $(OBJPATH)/CondVar.o + g++ Mutex.cpp -lpthread -c -g -o $(OBJPATH)/Mutex.o + #g++ Task.cpp -lpthread -c -g -o $(OBJPATH)/Task.o + g++ ThreadPool.cpp -lpthread -c -g -o $(OBJPATH)/ThreadPool.o + g++ Multi.cpp -lpthread -c -g -o $(OBJPATH)/Multi.o + #g++ $(OBJPATH)/CondVar.o $(OBJPATH)/Mutex.o $(OBJPATH)/Task.o $(OBJPATH)/ThreadPool.o threadpool_test.cpp Single.cpp Multi.cpp -lpthread -I . -g -o $(EXAMPLEPATH)threadpool_test + g++ $(OBJPATH)/CondVar.o $(OBJPATH)/Mutex.o $(OBJPATH)/ThreadPool.o threadpool_test.cpp Single.cpp Multi.cpp -lpthread -I . -g -o $(EXAMPLEPATH)threadpool_test + +#all: +# g++ threadpool.cpp -lpthread -fpic -c -o bin/obj/threadpool.o +# g++ -L./bin bin/obj/threadpool.o -lpthread threadpool_test.cpp -o bin/example/threadpool_test + +#threadpool: +# g++ threadpool.cpp -lpthread -fpic -c -o bin/obj/threadpool.o +# g++ -shared -fPIC bin/obj/threadpool.o -o bin/lib/libthreadpool.so +#example: +# g++ -L./bin/lib -lthreadpool threadpool_test.cpp -o threadpool_test diff --git a/slsDetectorSoftware/threadFiles/Multi.cpp b/slsDetectorSoftware/threadFiles/Multi.cpp new file mode 100644 index 000000000..02e34438e --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Multi.cpp @@ -0,0 +1,197 @@ +#include "Multi.h" +#include "Single.h" +#include "ThreadPool.h" + + + +#include +#include +#include +#include +using namespace std; + +char ans[1000]; +int threadflag = 1; + +Multi::Multi() { + numSingles = 1; + threadpool = 0; + for(int i=0;idestroy_threadpool(); + threadpool=0; + } + if(numSingles > 0) + threadpool = new ThreadPool(numSingles); + switch(threadpool->initialize_threadpool()){ + case -1: + cerr << "Failed to initialize thread pool!" << endl; + return 0; + case 0: + cout << "Not initializing threads, only one detector" << endl; + break; + default: + cout << "Initialized Threadpool" << endl; + break; + } + return 1; +} + +int Multi::destroyThreadPool(){ + if(threadpool){ + threadpool->destroy_threadpool(); + threadpool=0; + cout<<"Destroyed Threadpool"<* binder = + // new func_t(&Single::printNumber,singles[i],inum,iret[i]); + Task* task = new Task(new func1_t(&Single::printNumber,singles[i],inum,iret[i])); + threadpool->add_task(task); + } + threadpool->wait_for_tasks_to_complete(); + + + for(int i=0;i1){ + string* sret[numSingles]; + + + for(int i=0;i* binder = + new func1_t(&Single::printString,singles[i],s,sret[i]); + Task* task = new Task(binder); + threadpool->add_task(task); + } + threadpool->wait_for_tasks_to_complete(); + for(int i=0;iprintString(s); + if(ret=="error") + ret = ret1; + else if (ret != ret1) + ret = "sss"; + } + } + return ret; +} + +char* Multi::printCharArray(char a[]){ + string ret="error", ret1="sss"; + + if(numSingles>1){ + string* sret[numSingles]; + + for(int i=0;i* binder = + new func1_t (&Single::printCharArray,singles[i],a,sret[i]); + Task* task = new Task(binder); + threadpool->add_task(task); + } + threadpool->wait_for_tasks_to_complete(); + + for(int i=0;iprintCharArray(a); + if(ret=="error") + ret = ret1; + else if (ret != ret1) + ret = "sss"; + } + } + strcpy(ans,ret.c_str()); + return ans; +} diff --git a/slsDetectorSoftware/threadFiles/Multi.h b/slsDetectorSoftware/threadFiles/Multi.h new file mode 100644 index 000000000..b7216c579 --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Multi.h @@ -0,0 +1,36 @@ +#pragma once + + +#include "Global.h" + +#include +using namespace std; + +class Single; +class ThreadPool; + +class Multi { +public: + + Multi(); + ~Multi(); + + string executeCommand(int argc,char* argv[]); + + int printNumber(int inum); + string printString(string s); + char* printCharArray(char a[]); + + int createThreadPool(); + int destroyThreadPool(); + +protected: + Single* singles[MAX_SINGLES]; + int numSingles; + ThreadPool* threadpool; + + + +}; + + diff --git a/slsDetectorSoftware/threadFiles/Mutex.cpp b/slsDetectorSoftware/threadFiles/Mutex.cpp new file mode 100644 index 000000000..3f7cdca25 --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Mutex.cpp @@ -0,0 +1,26 @@ +#include "Mutex.h" + +Mutex::Mutex() { + pthread_mutex_init(&m_lock, NULL); + is_locked = false; +} + +Mutex::~Mutex() { + while(is_locked); + unlock(); // Unlock Mutex after shared resource is safe + pthread_mutex_destroy(&m_lock); +} + +void Mutex::lock() { + pthread_mutex_lock(&m_lock); + is_locked = true; +} + +void Mutex::unlock() { + is_locked = false; // do it BEFORE unlocking to avoid race condition + pthread_mutex_unlock(&m_lock); +} + +pthread_mutex_t* Mutex::get_mutex_ptr(){ + return &m_lock; +} diff --git a/slsDetectorSoftware/threadFiles/Mutex.h b/slsDetectorSoftware/threadFiles/Mutex.h new file mode 100644 index 000000000..a88df0d4e --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Mutex.h @@ -0,0 +1,27 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "Global.h" + +using namespace std; + +class Mutex +{ +public: + Mutex(); + ~Mutex(); + void lock(); + void unlock(); + pthread_mutex_t* get_mutex_ptr(); + +private: + pthread_mutex_t m_lock; + volatile bool is_locked; +}; diff --git a/slsDetectorSoftware/threadFiles/Single.cpp b/slsDetectorSoftware/threadFiles/Single.cpp new file mode 100644 index 000000000..43b0ca14b --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Single.cpp @@ -0,0 +1,37 @@ +#include "Single.h" + +#include +#include +using namespace std; + +char local_ans[1000]; + +Single::Single(int id) { + detID = id; + // cout<<"detID:"< +using namespace std; + +class Single { +public: + Single(int id); + ~Single(); + int getID(); + + int printNumber(int i); + string printString(string s); + char* printCharArray(char a[]); + +private: + int detID; + + int* someValue; + +}; + diff --git a/slsDetectorSoftware/threadFiles/Task.h b/slsDetectorSoftware/threadFiles/Task.h new file mode 100644 index 000000000..e7f8f12f8 --- /dev/null +++ b/slsDetectorSoftware/threadFiles/Task.h @@ -0,0 +1,159 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include "Global.h" +#include "sls_detector_defs.h" + +#include +using namespace std; + +class slsDetector; + +template +class func0_t{ +public: + func0_t(_Ret (_Class::*fn)(),_Class* ptr, _Store* sto): + m_fn(fn),m_ptr(ptr),m_store(sto){} + ~func0_t() {} + void operator()() const {*m_store = ((m_ptr->*m_fn)());} +private: + _Class* m_ptr; + _Ret (_Class::*m_fn)(); + _Store* m_store; +}; + +template +class func1_t{ +public: + func1_t(_Ret (_Class::*fn)(_Arg1),_Class* ptr,_Arg1 arg1, _Store* sto): + m_fn(fn),m_ptr(ptr),m_arg1(arg1),m_store(sto){} + ~func1_t() {} + void operator()() const {*m_store = ((m_ptr->*m_fn)(m_arg1));} +private: + _Class* m_ptr; + _Ret (_Class::*m_fn)(_Arg1); + _Arg1 m_arg1; + _Store* m_store; +}; + +template +class func2_t{ +public: + func2_t(_Ret (_Class::*fn)(_Arg1,_Arg2),_Class* ptr,_Arg1 arg1,_Arg2 arg2,_Store* sto): + m_fn(fn),m_ptr(ptr),m_arg1(arg1),m_arg2(arg2),m_store(sto){} + ~func2_t() {} + void operator()() const {*m_store = ((m_ptr->*m_fn)(m_arg1,m_arg2));} +private: + _Class* m_ptr; + _Ret (_Class::*m_fn)(_Arg1,_Arg2); + _Arg1 m_arg1; + _Arg2 m_arg2; + _Store* m_store; +}; + +template +class func3_t{ +public: + func3_t(_Ret (_Class::*fn)(_Arg1,_Arg2,_Arg3),_Class* ptr,_Arg1 arg1,_Arg2 arg2,_Arg3 arg3,_Store* sto): + m_fn(fn),m_ptr(ptr),m_arg1(arg1),m_arg2(arg2),m_arg3(arg3),m_store(sto){} + ~func3_t() {} + void operator()() const {*m_store = ((m_ptr->*m_fn)(m_arg1,m_arg2,m_arg3));} +private: + _Class* m_ptr; + _Ret (_Class::*m_fn)(_Arg1,_Arg2,_Arg3); + _Arg1 m_arg1; + _Arg2 m_arg2; + _Arg3 m_arg3; + _Store* m_store; +}; + +template +class func4_t{ +public: + func4_t(_Ret (_Class::*fn)(_Arg1,_Arg2,_Arg3,_Arg4),_Class* ptr,_Arg1 arg1,_Arg2 arg2,_Arg3 arg3,_Arg4 arg4,_Store* sto): + m_fn(fn),m_ptr(ptr),m_arg1(arg1),m_arg2(arg2),m_arg3(arg3),m_arg4(arg4),m_store(sto){} + ~func4_t() {} + void operator()() const {*m_store = ((m_ptr->*m_fn)(m_arg1,m_arg2,m_arg3,m_arg4));} +private: + _Class* m_ptr; + _Ret (_Class::*m_fn)(_Arg1,_Arg2,_Arg3,_Arg4); + _Arg1 m_arg1; + _Arg2 m_arg2; + _Arg3 m_arg3; + _Arg4 m_arg4; + _Store* m_store; +}; + +class Task: public virtual slsDetectorDefs{ +public: + /* Return: int, Param: int */ + Task(func1_t * t): m1(t),m2(0),m3(0),m4(0),m5(0),m6(0),m7(0),m8(0),m9(0),m10(0),m11(0){}; + /* Return: int, Param: string,int */ + Task(func2_t * t): m1(0),m2(t),m3(0),m4(0),m5(0),m6(0),m7(0),m8(0),m9(0),m10(0),m11(0){}; + /* Return: string, Param: string */ + Task(func1_t * t): m1(0),m2(0),m3(t),m4(0),m5(0),m6(0),m7(0),m8(0),m9(0),m10(0),m11(0){}; + /* Return: char*, Param: char* */ + Task(func1_t * t): m1(0),m2(0),m3(0),m4(t),m5(0),m6(0),m7(0),m8(0),m9(0),m10(0),m11(0){}; + /* Return: detectorSettings, Param: int */ + Task(func1_t * t): m1(0),m2(0),m3(0),m4(0),m5(t),m6(0),m7(0),m8(0),m9(0),m10(0),m11(0){}; + /* Return: detectorSettings, Param: detectorSettings,int */ + Task(func2_t * t): m1(0),m2(0),m3(0),m4(0),m5(0),m6(t),m7(0),m8(0),m9(0),m10(0),m11(0){}; + /* Return: int, Param: int,int */ + Task(func2_t * t): m1(0),m2(0),m3(0),m4(0),m5(0),m6(0),m7(t),m8(0),m9(0),m10(0),m11(0){}; + /* Return: int, Param: int,int */ + Task(func3_t * t): m1(0),m2(0),m3(0),m4(0),m5(0),m6(0),m7(0),m8(t),m9(0),m10(0),m11(0){}; + /* Return: int, Param: trimMode,int,int,int */ + Task(func4_t * t): m1(0),m2(0),m3(0),m4(0),m5(0),m6(0),m7(0),m8(0),m9(t),m10(0),m11(0){}; + /* Return: int, Param: int */ + Task(func0_t * t): m1(0),m2(0),m3(0),m4(0),m5(0),m6(0),m7(0),m8(0),m9(0),m10(t),m11(0){}; + /* Return: char*, Param: networkParameter,string,string */ + Task(func2_t * t): m1(0),m2(0),m3(0),m4(0),m5(0),m6(0),m7(0),m8(0),m9(0),m10(0),m11(t){}; + ~Task(){} + + void operator()(){ + if(m1) (*m1)(); + else if(m2) (*m2)(); + else if(m3) (*m3)(); + else if(m4) (*m4)(); + else if(m5) (*m5)(); + else if(m6) (*m6)(); + else if(m7) (*m7)(); + else if(m8) (*m8)(); + else if(m9) (*m9)(); + else if(m10) (*m10)(); + else if(m11) (*m11)(); + } + +private: + /* Return: int, Param: int */ + func1_t * m1; + /* Return: int, Param: string,int */ + func2_t * m2; + /* Return: string, Param: string */ + func1_t * m3; + /* Return: char*, Param: char* */ + func1_t * m4; + /* Return: detectorSettings, Param: int */ + func1_t * m5; + /* Return: detectorSettings, Param: detectorSettings,int */ + func2_t * m6; + /* Return: int, Param: int,int */ + func2_t * m7; + /* Return: int, Param: int,int */ + func3_t * m8; + /* Return: int, Param: trimMode,int,int,int */ + func4_t * m9; + /* Return: int, Param: int */ + func0_t * m10; + /* Return: char*, Param: networkParameter,string,string */ + func2_t * m11; +}; + + diff --git a/slsDetectorSoftware/threadFiles/ThreadPool.cpp b/slsDetectorSoftware/threadFiles/ThreadPool.cpp new file mode 100644 index 000000000..223983a73 --- /dev/null +++ b/slsDetectorSoftware/threadFiles/ThreadPool.cpp @@ -0,0 +1,170 @@ +#include "ThreadPool.h" + + +ThreadPool::ThreadPool(int pool_size) : m_pool_size(pool_size){ +#ifdef VERBOSE + cout << "Constructed ThreadPool of size " << m_pool_size << endl; +#endif + m_tasks_loaded = false; + thread_started = false; + current_thread_number = -1; + number_of_ongoing_tasks = 0; +} + +ThreadPool::~ThreadPool(){ + // Release resources + if (m_pool_state != STOPPED) { + destroy_threadpool(); + } +} + + +extern "C" +void* start_thread(void* arg) +{ + ThreadPool* tp = (ThreadPool*) arg; + tp->execute_thread(); + return NULL; +} + +int ThreadPool::initialize_threadpool(){ + if(m_pool_size == 1) + return m_pool_size; + + m_pool_state = STARTED; + int ret = -1; + sem_init(&semStart,1,0); + for (int i = 0; i < m_pool_size; i++) { + pthread_t tid; + thread_started = false; + current_thread_number = i; + ret = pthread_create(&tid, NULL, start_thread, (void*) this); + if (ret != 0) { + cerr << "pthread_create() failed: " << ret << endl; + return 0; + } + m_threads.push_back(tid); + while(!thread_started); + } +#ifdef VERBOSE + cout << m_pool_size << " threads created by the thread pool" << endl; +#endif + return m_pool_size; +} + +int ThreadPool::destroy_threadpool(){ + if(m_pool_size == 1) + return 0; + /*cout << "in destroying threadpool" << endl;*/ + // thread communication- modified m_pool_state may not show up + //to other threads until its modified in a lock! + m_task_mutex.lock(); + m_pool_state = STOPPED; + m_task_mutex.unlock(); + /*cout << "Broadcasting STOP signal to all threads..." << endl;*/ + m_task_cond_var.broadcast(); // notify all threads we are shttung down + + int ret = -1; + for (int i = 0; i < m_pool_size; i++) { + void* result; + sem_post(&semStart); + ret = pthread_join(m_threads[i], &result); + /*cout << "pthread_join() returned " << ret << ": " << strerror(errno) << endl;*/ + m_task_cond_var.broadcast(); // try waking up a bunch of threads that are still waiting + } + sem_destroy(&semStart); + number_of_ongoing_tasks = 0; + /* cout << m_pool_size << " threads exited from the thread pool" << endl;*/ + return 0; +} + +void* ThreadPool::execute_thread(){ + int ithread = current_thread_number; + thread_started = true; + Task* task = NULL; + m_tasks_loaded = false; + /*cout << "Starting thread " << pthread_self() << endl;*/ + while(true) { + // Try to pick a task + /*cout << "Locking: " << pthread_self() << endl;*/ + m_task_mutex.lock(); + + while ((m_pool_state != STOPPED) && (m_tasks.empty())) { + // Wait until there is a task in the queue + // Unlock mutex while wait, then lock it back when signaled + /* cout << "Unlocking and waiting: " << pthread_self() << endl;*/ + m_task_cond_var.wait(m_task_mutex.get_mutex_ptr()); + /* cout << "Signaled and locking: " << pthread_self() << endl;*/ + } + + // If the thread was woken up to notify process shutdown, return from here + if (m_pool_state == STOPPED) { + /* cout << "Unlocking and exiting: " << pthread_self() << endl;*/ + m_task_mutex.unlock(); + pthread_exit(NULL); + } + + task = m_tasks.front(); + m_tasks.pop_front(); + /*cout << "Unlocking: " << pthread_self() << endl;*/ + m_task_mutex.unlock(); + + sem_wait(&semStart); + + /*cout << ithread <<" Executing thread " << pthread_self() << endl;*/ + // execute the task + (*task)(); // could also do task->run(arg); + /*cout << ithread <<" Done executing thread " << pthread_self() << endl;*/ + + m_all_tasks_mutex.lock(); + number_of_ongoing_tasks--; + m_all_tasks_mutex.unlock(); + + //last task and check m_tasks_loaded to ensure done only once + if((!number_of_ongoing_tasks) && m_tasks_loaded){ + /*cout << ithread << " all tasks done."< +#include +#include +#include +#include +#include +#include +#include + +#include "Mutex.h" +#include "Task.h" +#include "CondVar.h" +#include "Global.h" +#include +using namespace std; + + +class ThreadPool +{ +public: + ThreadPool(int pool_size); + ~ThreadPool(); + int initialize_threadpool(); + int destroy_threadpool(); + void* execute_thread(); + int add_task(Task* task); + void wait_for_tasks_to_complete(); + +private: + int m_pool_size; + Mutex m_task_mutex; + CondVar m_task_cond_var; + std::vector m_threads; // storage for threads + std::deque m_tasks; + volatile int m_pool_state; + + Mutex m_all_tasks_mutex; + CondVar m_all_tasks_cond_var; + bool m_tasks_loaded; + bool thread_started; + int current_thread_number; + + //volatile uint64_t tasks_done_mask; + volatile int number_of_ongoing_tasks; + + sem_t semStart; + +}; + diff --git a/slsDetectorSoftware/threadFiles/bin/examplethreadpool_test b/slsDetectorSoftware/threadFiles/bin/examplethreadpool_test new file mode 100755 index 000000000..621d57a47 Binary files /dev/null and b/slsDetectorSoftware/threadFiles/bin/examplethreadpool_test differ diff --git a/slsDetectorSoftware/threadFiles/threadpool_test.cpp b/slsDetectorSoftware/threadFiles/threadpool_test.cpp new file mode 100644 index 000000000..2dbd2c416 --- /dev/null +++ b/slsDetectorSoftware/threadFiles/threadpool_test.cpp @@ -0,0 +1,61 @@ +//#include "ThreadPool.h" + +//#include "threadpool.h" + +#include +#include + +#include "Multi.h" +using namespace std; + +//const int MAX_TASKS = 4; + +/* +void hello(void* arg) +{ + string* x = (string*) arg; + cout << "Hello: " << *x << endl; +// cout << "\n"; +} +*/ +int main(int argc, char* argv[]) +{ + + Multi* m = new Multi(); + cout<<"Answer:"<< m->executeCommand(argc,argv) << endl; + delete m; + /* + ThreadPool tp(2); + int ret = tp.initialize_threadpool(); + if (ret == -1) { + cerr << "Failed to initialize thread pool!" << endl; + return 0; + } +*/ + + +/* + for (int i = 0; i < MAX_TASKS; i++) { + cout<<"adding task:" < + +/* + contains the conversion channel-angle for a module channel + conv_r=pitch/radius +*/ +#define PI 3.14159265358979323846 +#include + +double defaultAngleFunction(double ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) {\ + (void) tilt; + double ang; + + ang=180./PI*(center*conv_r+direction*atan((double)(ichan-center)*conv_r))+encoder+totalOffset+offset; + + + //#ifdef VERBOSE + // printf("%d %f %f %f %f %f %f %d\n", ichan, ang, center, encoder, totalOffset, conv_r, offset, direction); + //#endif + + return ang; \ + return 180./PI*(center*conv_r+direction*atan((double)(ichan-center)*conv_r))+encoder+totalOffset+offset; }; + +#endif diff --git a/slsDetectorSoftware/usersFunctions/usersFunctions.cpp b/slsDetectorSoftware/usersFunctions/usersFunctions.cpp new file mode 100644 index 000000000..0d7b5318a --- /dev/null +++ b/slsDetectorSoftware/usersFunctions/usersFunctions.cpp @@ -0,0 +1,347 @@ +#include "usersFunctions.h" +#include +#include + + +float pos; +float i0=0; +#ifdef EPICS + +#include +#include + +static double timeout = 3.0; + +chid ch_pos,ch_i0, ch_getpos; + + + + +/* connect to a PV */ +int connect_channel(const char *name, chid *ch_id) { + int status = ECA_NORMAL; + status = ca_create_channel(name, NULL, NULL, CA_PRIORITY_DEFAULT, ch_id); + if (status != ECA_NORMAL) + return status; + + status = ca_pend_io(timeout); + return status; +} + +/* disconnect to a PV */ +int disconnect_channel(chid ch_id) +{ + ca_clear_channel(ch_id); + ca_flush_io(); +} + +int caget(chid ch_id, double *value) { + + int status = ECA_NORMAL; + + status = ca_get(DBR_DOUBLE, ch_id, value); + if (status != ECA_NORMAL) { + return status; + } + + status = ca_pend_io(timeout); + if (status != ECA_NORMAL) { + return status; + } + + return status; +} + +int caputq(chid ch_id, double value) { + // does not wait! + int status = ECA_NORMAL; + + status = ca_put(DBR_DOUBLE, ch_id, &value); + if (status != ECA_NORMAL) + return status; + + status = ca_pend_io(timeout); + if (status != ECA_NORMAL) { + return status; + } + + return status; +} + +void put_callback(struct event_handler_args args) +{ + epicsEventId eid = (epicsEventId)args.usr; + epicsEventSignal(eid); +} + +int caput(chid ch_id, double value) { + + // waits! + int status = ECA_NORMAL; + epicsEventId eid = epicsEventCreate(epicsEventEmpty); + + status = ca_put_callback(DBR_DOUBLE, + ch_id, + &value, + put_callback, + eid); + status = ca_pend_io(timeout); + if (status != ECA_NORMAL) + return status; + + if (epicsEventWait(eid) != epicsEventWaitOK) + status = ECA_TIMEOUT; + + return status; +} + +//int main(int argc, char *argv[]) { + + + + + + + + +#endif + + + + + + + +// /* +// contains the conversion channel-angle for a module channel +// conv_r=pitch/radius +// */ + + +// double defaultAngleFunction(double ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction) { + + +// (void) tilt; /* to avoid warning: unused parameter */ +// double ang; + +// ang=180./PI*(center*conv_r+direction*atan((double)(ichan-center)*conv_r))+encoder+totalOffset+offset; + + +// //#ifdef VERBOSE +// printf("%d %f \n", ichan, ang); +// //#endif + +// return ang; + +// } + +/* reads the encoder and returns the position */ + +double defaultGetPosition(void*) { +#ifdef VERBOSE + printf("Getting motor position \n"); +#endif + // caget X04SA-ES2-TH2:RO.RBV + +#ifdef EPICS + int status; + + double value = 256; + if (ch_getpos<0) return -1; + +/* /\* caget *\/ */ + if (caget(ch_getpos, &value) == ECA_NORMAL) { +#ifdef VERBOSE + printf("caget: %f\n", value); +#endif + pos=value; + } else + printf(ca_message(status)); +#endif + + + + return pos; +} + +/* moves the encoder to position p */ + + +int defaultGoToPosition(double p, void*) { +#ifdef VERBOSE + printf("Setting motor position \n"); +#endif + +#ifdef EPICS + int status; + if (ch_pos<0) return -1; + /* /\* caput and wait until done *\/ */ + if ((status = caput(ch_pos, p)) == ECA_NORMAL) { + ; +#ifdef VERBOSE + printf("caput %f: success\n", p); +#endif + } else + printf(ca_message(status)); +#else + pos=p; +#endif + //"caputq X04SA-ES2-TH2:RO p" + //cawait -nounit -timeout 3600 X04SA-ES2-TH2:RO.DMOV '==1' + + return (int)p; +} + +/* moves the encoder to position p without waiting */ + +int defaultGoToPositionNoWait(double p, void*) { +#ifdef VERBOSE + printf("Setting motor position no wait \n"); +#endif + + +#ifdef EPICS + int status; + if (ch_pos<0) return -1; + /* /\* caput and wait until done *\/ */ + if ((status = caputq(ch_pos, p)) == ECA_NORMAL) { + ; +#ifdef VERBOSE + printf("caputq: success\n"); +#endif + } else + printf(ca_message(status)); +#else + pos=p; +#endif + //"caputq X04SA-ES2-TH2:RO p" + + return (int)p; + + pos=p; + return (int)pos; +} + + +/* reads I0 and returns the intensity */ + +double defaultGetI0(int t, void*) { +#ifdef VERBOSE + printf("Getting I0 readout \n"); +#endif + +#ifdef EPICS + int status; + + double value = 256; +/* /\* caget *\/ */ + if (ch_i0<0) return -1; + if (caget(ch_i0, &value) == ECA_NORMAL) { +#ifdef VERBOSE + printf("caget: %f\n", value); +#endif + + + if (t==0) + i0=value; + else + i0=value-i0; + + + + } else + printf(ca_message(status)); +#else + i0++; +#endif + + //"ca_get X04SA-ES2-SC:CH6" + return i0; + +} + + +int defaultConnectChannels(void *) { +#ifdef EPICS + //double value = 256; + /* channel name */ + //const char *name = "ARIDI-PCT:CURRENT"; + /* channel id */ + /* status code */ + int status; + +#ifdef VERBOSE + printf("starting...\n"); +#endif + + /* init channel access context before any caget/put */ + ca_context_create(ca_enable_preemptive_callback); +#ifdef VERBOSE + printf("context created\n"); +#endif + //"caputq X04SA-ES2-TH2:RO p" + + //"ca_get X04SA-ES2-SC:CH6" + + /* open the channel by name and return ch_id */ + status = connect_channel("X04SA-ES2-SC:CH6", &ch_i0); + if (status == ECA_NORMAL) { +#ifdef VERBOSE + printf("I0 channel connected \n"); +#endif + ; + } else { + printf(ca_message(status)); + //ch_i0=-1;; + } + status = connect_channel("X04SA-ES2-TH2:RO", &ch_pos); + if (status == ECA_NORMAL) { +#ifdef VERBOSE + printf("Detector position channel connected \n"); +#endif + ; + } else { + printf(ca_message(status)); + //ch_i0=-1;; + } + status = connect_channel("X04SA-ES2-TH2:RO.RBV", &ch_getpos); + if (status == ECA_NORMAL) { +#ifdef VERBOSE + printf("Detector get position channel connected \n"); +#endif + ; + } else { + printf(ca_message(status)); + //ch_getpos=-1;; + } + + // caget X04SA-ES2-TH2:RO.RBV + + //cawait -nounit -timeout 3600 X04SA-ES2-TH2:RO.DMOV '==1' +#endif + return 0; +} + +int defaultDisconnectChannels(void*) { +#ifdef EPICS + /* close channel connect */ + disconnect_channel(ch_i0); + disconnect_channel(ch_pos); + disconnect_channel(ch_getpos); + + /* delete channel access context before program exits */ + ca_context_destroy(); +#endif + return 0; +} + + + +int defaultDataReadyFunc(detectorData* d) { +#ifdef VERBOSE + printf("UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU Data received \n"); +#endif + return 0; +} + + diff --git a/slsDetectorSoftware/usersFunctions/usersFunctions.h b/slsDetectorSoftware/usersFunctions/usersFunctions.h new file mode 100644 index 000000000..d2cc60f71 --- /dev/null +++ b/slsDetectorSoftware/usersFunctions/usersFunctions.h @@ -0,0 +1,49 @@ +#ifndef USERS_FUNCTIONS_H +#define USERS_FUNCTIONS_H +/****************************************************************** + +Functions depending on the experimental setup should be defined here + +******************************************************************/ + +#define PI 3.14159265358979323846 + + +#ifdef EPICS +#include +#include +#endif +#include "detectorData.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef EPICS + int connect_channel(const char *name, chid *ch_id); + int disconnect_channel(chid ch_id); + int caget(chid ch_id, double *value); + int caputq(chid ch_id, double value); + void put_callback(struct event_handler_args args); + int caput(chid ch_id, double value); +#endif + + + // double defaultAngleFunction(double ichan, double encoder, double totalOffset, double conv_r, double center, double offset, double tilt, int direction); + double defaultGetPosition(void*); + int defaultGoToPosition(double p, void*); + int defaultGoToPositionNoWait(double p, void*); + int defaultConnectChannels(void*); + int defaultDisconnectChannels(void*); + double defaultGetI0(int t, void*); + + int defaultDataReadyFunc(detectorData* d, void*); + + + +#ifdef __cplusplus +}; +#endif + + +#endif