From 794b6f80906939afc95b5bd9d014fe49629f90e2 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 22 Aug 2019 10:58:03 +0200 Subject: [PATCH 1/5] added detector type --- slsSupportLib/include/sls_detector_defs.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index a3f854b32..1116f8fb8 100755 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -86,7 +86,8 @@ class slsDetectorDefs { GOTTHARD, /**< gotthard */ JUNGFRAU, /**< jungfrau */ CHIPTESTBOARD, /**< CTB */ - MOENCH /**< moench */ + MOENCH, /**< moench */ + MYTHEN3 /** mythen3 */ }; /** @@ -576,8 +577,8 @@ format }; /** returns detector type string from detector type index - \param t string can be EIGER, GOTTHARD, JUNGFRAU, CHIPTESTBOARD - \returns Eiger, Gotthard, Jungfrau, JungfrauCTB, Unknown + \param t string can be EIGER, GOTTHARD, JUNGFRAU, CHIPTESTBOARD, MYTHEN3 + \returns Eiger, Gotthard, Jungfrau, JungfrauCTB, Mythen3, Unknown */ static std::string detectorTypeToString(detectorType t) { switch (t) { @@ -591,14 +592,16 @@ format return std::string("JungfrauCTB"); case MOENCH: return std::string("Moench"); + case MYTHEN3: + return std::string("Mythen3"); default: return std::string("Unknown"); } }; /** returns detector type index from detector type string - \param type can be Eiger, Gotthard, Jungfrau, JungfrauCTB - \returns EIGER, GOTTHARD, JUNGFRAU, CHIPTESTBOARD, GENERIC + \param type can be Eiger, Gotthard, Jungfrau, JungfrauCTB, Mythen3 + \returns EIGER, GOTTHARD, JUNGFRAU, CHIPTESTBOARD, MYTHEN3, GENERIC */ static detectorType detectorTypeToEnum(const std::string &type) { if (type == "Eiger") @@ -611,6 +614,8 @@ format return CHIPTESTBOARD; if (type == "Moench") return MOENCH; + if (type == "Mythen3") + return MYTHEN3; return GENERIC; }; From 72362b0334a6bd974a5466018cc6261a87901035 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 22 Aug 2019 12:34:06 +0200 Subject: [PATCH 2/5] first version of mythen3 --- slsDetectorServers/CMakeLists.txt | 3 +- .../mythen3DetectorServer/CMakeLists.txt | 31 ++ .../mythen3DetectorServer/Makefile | 37 ++ .../mythen3DetectorServer/RegisterDefs.h | 9 + .../slsDetectorFunctionList.c | 325 ++++++++++++++++++ .../slsDetectorServer_defs.h | 11 + .../slsDetectorFunctionList.h | 18 +- .../slsDetectorServer_funcs.c | 39 ++- slsSupportLib/include/versionAPI.h | 2 + 9 files changed, 458 insertions(+), 17 deletions(-) create mode 100644 slsDetectorServers/mythen3DetectorServer/CMakeLists.txt create mode 100755 slsDetectorServers/mythen3DetectorServer/Makefile create mode 100644 slsDetectorServers/mythen3DetectorServer/RegisterDefs.h create mode 100644 slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c create mode 100644 slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h diff --git a/slsDetectorServers/CMakeLists.txt b/slsDetectorServers/CMakeLists.txt index 7a05de417..309e6c7cc 100644 --- a/slsDetectorServers/CMakeLists.txt +++ b/slsDetectorServers/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(ctbDetectorServer) add_subdirectory(eigerDetectorServer) add_subdirectory(gotthardDetectorServer) add_subdirectory(jungfrauDetectorServer) -#add_subdirectory(moenchDetectorServer) \ No newline at end of file +#add_subdirectory(moenchDetectorServer) +add_subdirectory(mythen3DetectorServer) \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt new file mode 100644 index 000000000..5ae60dbb4 --- /dev/null +++ b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt @@ -0,0 +1,31 @@ +add_executable(mythen3DetectorServer + slsDetectorFunctionList.c + ../slsDetectorServer/slsDetectorServer.c + ../slsDetectorServer/slsDetectorServer_funcs.c + ../slsDetectorServer/communication_funcs.c +) + +include_directories( + ../slsDetectorServer/ + ../../slsSupportLib/include +) + +target_include_directories(mythen3DetectorServer + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} +) + +target_compile_definitions(mythen3DetectorServer + PUBLIC MYTHEN3D VIRTUAL STOP_SERVER +) + +target_link_libraries(mythen3DetectorServer + PUBLIC pthread rt +) + +set_target_properties(mythen3DetectorServer PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) + +install(TARGETS mythen3DetectorServer + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) diff --git a/slsDetectorServers/mythen3DetectorServer/Makefile b/slsDetectorServers/mythen3DetectorServer/Makefile new file mode 100755 index 000000000..c4eae2be0 --- /dev/null +++ b/slsDetectorServers/mythen3DetectorServer/Makefile @@ -0,0 +1,37 @@ +current_dir = $(shell pwd) +main_server = ../slsDetectorServer/ +support_lib = ../../slsSupportLib/include/ + +CROSS = bfin-uclinux- +CC = $(CROSS)gcc +CFLAGS += -Wall -DMYTHEN3D -DSTOP_SERVER -I$(main_server) -I$(support_lib) -I$(current_dir)#-DVERBOSEI #-DVERBOSE +LDLIBS += -lm +PROGS = mythen3DetectorServer +DESTDIR ?= bin +INSTMODE = 0777 + +SRCS = $(main_server)communication_funcs.c $(main_server)slsDetectorServer.c $(main_server)slsDetectorServer_funcs.c slsDetectorFunctionList.c +OBJS = $(SRCS:.c=.o) + +all: clean versioning $(PROGS) + +boot: $(OBJS) + +version_name=APIMYTHEN3 +version_path=slsDetectorServers/mythen3DetectorServer +versioning: + cd ../../ && echo $(PWD) && echo `tput setaf 6; ./updateAPIVersion.sh $(version_name) $(version_path); tput sgr0;` + + +$(PROGS): $(OBJS) +# echo $(OBJS) + mkdir -p $(DESTDIR) + $(CC) -o $@ $^ $(CFLAGS) $(LDLIBS) + mv $(PROGS) $(DESTDIR) + rm *.gdb + +clean: + rm -rf $(DESTDIR)/$(PROGS) *.o *.gdb $(main_server)*.o + + + \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h new file mode 100644 index 000000000..ab2d110c8 --- /dev/null +++ b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h @@ -0,0 +1,9 @@ +#pragma once + +/* Definitions for FPGA*/ +#define MEM_MAP_SHIFT 1 + + +/* Status register */ +#define STATUS_REG (0x02 << MEM_MAP_SHIFT) + diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c new file mode 100644 index 000000000..b2d1277cd --- /dev/null +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -0,0 +1,325 @@ +#include "slsDetectorFunctionList.h" +#include "versionAPI.h" +#include "clogger.h" + +#ifdef VIRTUAL +#include "communication_funcs_UDP.h" +#include +#include +#endif +#include +#include // usleep +#include "blackfin.h" + + +// Global variable from slsDetectorServer_funcs +extern int debugflag; + +int firmware_compatibility = OK; +int firmware_check_done = 0; +char firmware_message[MAX_STR_LENGTH]; + +#ifdef VIRTUAL +pthread_t pthread_virtual_tid; +int virtual_status = 0; +int virtual_stop = 0; +#endif + + + +int isFirmwareCheckDone() { + return firmware_check_done; +} + +int getFirmwareCheckResult(char** mess) { + *mess = firmware_message; + return firmware_compatibility; +} + +void basictests() { + firmware_compatibility = OK; + firmware_check_done = 0; + memset(firmware_message, 0, MAX_STR_LENGTH); +#ifdef VIRTUAL + FILE_LOG(logINFOBLUE, ("******** Mythen3 Virtual Server *****************\n")); + if (mapCSP0() == FAIL) { + strcpy(firmware_message, + "Could not map to memory. Dangerous to continue.\n"); + FILE_LOG(logERROR, (firmware_message)); + firmware_compatibility = FAIL; + firmware_check_done = 1; + return; + } + firmware_check_done = 1; + return; +#else + + +#endif +} + +/* Ids */ + +int64_t getDetectorId(enum idMode arg){ + int64_t retval = -1; + + switch(arg){ + case DETECTOR_SERIAL_NUMBER: + return getDetectorNumber();// or getDetectorMAC() + case DETECTOR_FIRMWARE_VERSION: + return getFirmwareVersion(); + case SOFTWARE_FIRMWARE_API_VERSION: + return getFirmwareAPIVersion(); + case DETECTOR_SOFTWARE_VERSION: + case CLIENT_SOFTWARE_API_VERSION: + return APIMYTHEN3; + default: + return retval; + } +} + +u_int64_t getFirmwareVersion() { +#ifdef VIRTUAL + return 0; +#endif + return 0; +} + +u_int64_t getFirmwareAPIVersion() { +#ifdef VIRTUAL + return 0; +#endif + return 0; +} + +u_int32_t getDetectorNumber(){ +#ifdef VIRTUAL + return 0; +#endif + return 0; +} + + +u_int64_t getDetectorMAC() { +#ifdef VIRTUAL + return 0; +#else + 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; +#endif +} + +u_int32_t getDetectorIP(){ +#ifdef VIRTUAL + return 0; +#endif + char temp[50]=""; + u_int32_t 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); + //FILE_LOG(logINFO, ("ip:%x\n",res); + + return res; +} + + +/* initialization */ + +void initControlServer(){ + setupDetector(); +} + +void initStopServer() { + + usleep(CTRL_SRVR_INIT_TIME_US); + if (mapCSP0() == FAIL) { + FILE_LOG(logERROR, ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); + exit(EXIT_FAILURE); + } +} + + +/* set up detector */ + +void setupDetector() { + FILE_LOG(logINFO, ("This Server is for 1 Mythen3 module \n")); +} + + +/* set parameters - dr, roi */ + +int setDynamicRange(int dr){ + return -1; +} + + +/* parameters - speed, readout */ + +void setSpeed(enum speedVariable ind, int val) { + +} + +int getSpeed(enum speedVariable ind) { + return -1; +} + +int64_t setTimer(enum timerIndex ind, int64_t val) { + + switch(ind){ + + case FRAME_NUMBER: + + case ACQUISITION_TIME: + + case FRAME_PERIOD: + + case CYCLES_NUMBER: + return -1; + + default: + break; + } + + return -1; + +} + +int validateTimer(enum timerIndex ind, int64_t val, int64_t retval) { + + switch(ind) { + case ACQUISITION_TIME: + + case FRAME_PERIOD: + + default: + break; + } + return OK; +} + + +int64_t getTimeLeft(enum timerIndex ind){ +#ifdef VIRTUAL + return 0; +#endif + + return -1; +} + +int startStateMachine(){ +#ifdef VIRTUAL + // create udp socket + if(createUDPSocket(0) != OK) { + return FAIL; + } + FILE_LOG(logINFOBLUE, ("starting state machine\n")); + virtual_status = 1; + virtual_stop = 0; + if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { + FILE_LOG(logERROR, ("Could not start Virtual acquisition thread\n")); + virtual_status = 0; + return FAIL; + } + FILE_LOG(logINFOGREEN, ("Virtual Acquisition started\n")); + return OK; +#endif + return OK; +} + + +#ifdef VIRTUAL +void* start_timer(void* arg) { + int64_t periodns = setTimer(FRAME_PERIOD, -1); + int numFrames = (setTimer(FRAME_NUMBER, -1) * + setTimer(CYCLES_NUMBER, -1) ); + int64_t exp_ns = setTimer(ACQUISITION_TIME, -1); + + + int frameNr = 0; + for(frameNr=0; frameNr!= numFrames; ++frameNr ) { + int srcOffset = 0; + + struct timespec begin, end; + clock_gettime(CLOCK_REALTIME, &begin); + + usleep(exp_ns / 1000); + + clock_gettime(CLOCK_REALTIME, &end); + int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + + (end.tv_nsec - begin.tv_nsec)); + + if (periodns > time_ns) { + usleep((periodns - time_ns)/ 1000); + } + } + + virtual_status = 0; + return NULL; +} +#endif + + +int stopStateMachine(){ + FILE_LOG(logINFORED, ("Stopping State Machine\n")); +#ifdef VIRTUAL + virtual_stop = 0; + return OK; +#endif + return OK; +} + +enum runStatus getRunStatus(){ +#ifdef VIRTUAL + if(virtual_status == 0){ + FILE_LOG(logINFOBLUE, ("Status: IDLE\n")); + return IDLE; + }else{ + FILE_LOG(logINFOBLUE, ("Status: RUNNING\n")); + return RUNNING; + } +#endif + return IDLE; +} + +void readFrame(int *ret, char *mess){ +#ifdef VIRTUAL + FILE_LOG(logINFOGREEN, ("acquisition successfully finished\n")); + return; +#endif +} + +/* common */ + +int calculateDataBytes(){ + return 0; +} + +int getTotalNumberOfChannels(){return ((int)getNumberOfChannelsPerChip() * (int)getNumberOfChips());} +int getNumberOfChips(){return NCHIP;} +int getNumberOfDACs(){return NDAC;} +int getNumberOfChannelsPerChip(){return NCHAN;} \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h new file mode 100644 index 000000000..866af52fd --- /dev/null +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h @@ -0,0 +1,11 @@ +#pragma once +#include "sls_detector_defs.h" +#include "RegisterDefs.h" + + +#define CTRL_SRVR_INIT_TIME_US (300 * 1000) + +/* Hardware Definitions */ +#define NCHAN (128) +#define NCHIP (10) +#define NDAC (16) \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h index b6de7aff7..c1360b733 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/slsDetectorFunctionList.h @@ -150,17 +150,19 @@ int getStartingFrameNumber(uint64_t* value); #endif int64_t setTimer(enum timerIndex ind, int64_t val); int64_t getTimeLeft(enum timerIndex ind); -#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) +#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D) int validateTimer(enum timerIndex ind, int64_t val, int64_t retval); #endif // parameters - module, settings -#if (!defined(CHIPTESTBOARDD)) && (!defined(MOENCHD)) +#if (!defined(CHIPTESTBOARDD)) && (!defined(MOENCHD)) && (!defined(MYTHEN3D)) int setModule(sls_detector_module myMod, char* mess); int getModule(sls_detector_module *myMod); enum detectorSettings setSettings(enum detectorSettings sett); #endif +#ifndef MYTHEN3D enum detectorSettings getSettings(); +#endif // parameters - threshold #ifdef EIGERD @@ -180,9 +182,11 @@ extern int AD9257_GetVrefVoltage(int mV); // AD9257.h extern int AD9257_SetVrefVoltage(int val, int mV); // AD9257.h #endif +#ifndef MYTHEN3D void setDAC(enum DACINDEX ind, int val, int mV); int getDAC(enum DACINDEX ind, int mV); int getMaxDacSteps(); +#endif #if defined(CHIPTESTBOARDD) || defined(MOENCHD) int dacToVoltage(int dac); int checkVLimitCompliant(int mV); @@ -205,16 +209,20 @@ void powerOff(); #endif #ifndef MOENCHD +#ifndef MYTHEN3D int getADC(enum ADCINDEX ind); #endif - +#endif +#ifndef MYTHEN3D int setHighVoltage(int val); - +#endif // parameters - timing, extsig +#ifndef MYTHEN3D void setTiming( enum timingMode arg); enum timingMode getTiming(); +#endif #ifdef GOTTHARDD void setExtSignal(enum externalSignalFlag mode); int getExtSignal(); @@ -245,8 +253,10 @@ int configureMAC(int numInterfaces, int selInterface, uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport, uint32_t destip2, uint64_t destmac2, uint64_t sourcemac2, uint32_t sourceip2, uint32_t udpport2); #else +#ifndef MYTHEN3D int configureMAC(uint32_t destip, uint64_t destmac, uint64_t sourcemac, uint32_t sourceip, uint32_t udpport); #endif +#endif #if defined(JUNGFRAUD) || defined(EIGERD) int setDetectorPosition(int pos[]); diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c index f6aa66775..373eafa83 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c @@ -529,6 +529,10 @@ int set_timing_mode(int file_des) { return printSocketReadError(); FILE_LOG(logDEBUG1, ("Setting external communication mode to %d\n", arg)); +#ifdef MYTHEN3D + functionNotImplemented(); +#else + // set if ((arg != GET_TIMING_MODE) && (Server_VerifyLock() == OK)) { switch (arg) { @@ -549,6 +553,8 @@ int set_timing_mode(int file_des) { retval = getTiming(); validate((int)arg, (int)retval, "set timing mode", DEC); FILE_LOG(logDEBUG1, ("Timing Mode: %d\n",retval)); +#endif + return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); } @@ -603,7 +609,7 @@ int digital_test(int file_des) { FILE_LOG(logDEBUG1, ("Digital test, mode = %d\n", mode)); #endif -#ifdef EIGERD +#if defined(EIGERD) || defined(MYTHEN3D) functionNotImplemented(); #else // only set @@ -643,6 +649,11 @@ int set_dac(int file_des) { if (receiveData(file_des, args, sizeof(args), INT32) < 0) return printSocketReadError(); + +#ifdef MYTHEN3D + functionNotImplemented(); +#else + enum dacIndex ind = args[0]; int mV = args[1]; int val = args[2]; @@ -989,6 +1000,7 @@ int set_dac(int file_des) { } } } +#endif return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); } @@ -1006,7 +1018,7 @@ int get_adc(int file_des) { if (receiveData(file_des, &ind, sizeof(ind), INT32) < 0) return printSocketReadError(); -#ifdef MOENCHD +#if defined(MOENCHD) || defined(MYTHEN3D) functionNotImplemented(); #else enum ADCINDEX serverAdcIndex = 0; @@ -1185,7 +1197,7 @@ int set_module(int file_des) { memset(mess, 0, sizeof(mess)); enum detectorSettings retval = -1; -#if defined(CHIPTESTBOARDD) || defined(MOENCHD) +#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D) functionNotImplemented(); #else @@ -1315,7 +1327,7 @@ int get_module(int file_des) { } else module.dacs = myDac; -#if defined(CHIPTESTBOARDD) || defined(MOENCHD) +#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D) functionNotImplemented(); #endif @@ -1340,7 +1352,7 @@ int get_module(int file_des) { // only get FILE_LOG(logDEBUG1, ("Getting module\n")); -#if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) +#if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(MYTHEN3D) getModule(&module); #endif FILE_LOG(logDEBUG1, ("Getting module. Settings:%d\n", module.reg)); @@ -1371,7 +1383,7 @@ int set_settings(int file_des) { if (receiveData(file_des, &isett, sizeof(isett), INT32) < 0) return printSocketReadError(); -#if defined(CHIPTESTBOARDD) || defined(MOENCHD) +#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D) functionNotImplemented(); #else FILE_LOG(logDEBUG1, ("Setting settings %d\n", isett)); @@ -1844,7 +1856,7 @@ int set_readout_flags(int file_des) { return printSocketReadError(); FILE_LOG(logDEBUG1, ("Setting readout flags to %d\n", arg)); -#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(MOENCHD) +#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(MOENCHD) || defined(MYTHEN3D) functionNotImplemented(); #else // set & get @@ -2293,8 +2305,11 @@ int configure_mac(int file_des) { if (receiveData(file_des, args, sizeof(args), OTHER) < 0) return printSocketReadError(); - FILE_LOG(logDEBUG1, ("\n Configuring MAC\n")); +#if defined(MYTHEN3D) + functionNotImplemented(); +#else + FILE_LOG(logDEBUG1, ("\n Configuring MAC\n")); // dest port uint32_t dstPort = 0; sscanf(args[0], "%x", &dstPort); @@ -2486,7 +2501,7 @@ int configure_mac(int file_des) { } } } - +#endif return Server_SendResult(file_des, OTHER, UPDATE, retvals, sizeof(retvals)); } @@ -2502,7 +2517,7 @@ int enable_ten_giga(int file_des) { return printSocketReadError(); FILE_LOG(logDEBUG1, ("Enable/ Disable 10GbE : %d\n", arg)); -#if defined(JUNGFRAUD) || defined(GOTTHARDD) +#if defined(JUNGFRAUD) || defined(GOTTHARDD) || defined(MYTHEN3D) functionNotImplemented(); #else // set & get @@ -3074,7 +3089,7 @@ int set_network_parameter(int file_des) { int value = args[1]; FILE_LOG(logDEBUG1, ("Set network parameter index %d to %d\n", mode, value)); -#if defined(GOTTHARDD) || defined (CHIPTESTBOARDD) || defined(MOENCHD) +#if defined(GOTTHARDD) || defined (CHIPTESTBOARDD) || defined(MOENCHD) || defined(MYTHEN3D) functionNotImplemented(); #else enum NETWORKINDEX serverIndex = 0; @@ -3131,7 +3146,7 @@ int program_fpga(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); -#if defined(EIGERD) || defined(GOTTHARDD) +#if defined(EIGERD) || defined(GOTTHARDD) || defined(MYTHEN3D) //to receive any arguments int n = 1; while (n > 0) diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index d1e8858e4..6a31604fe 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -8,3 +8,5 @@ #define APIGOTTHARD 0x190821 #define APIJUNGFRAU 0x190821 #define APIEIGER 0x190821 + +#define APIMYTHEN3 0x190822 From 4b7ab98135d4462e023fffdee4e3a580a7a6d85e Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 22 Aug 2019 15:55:27 +0200 Subject: [PATCH 3/5] initial functions for mythen3 --- .../mythen3DetectorServer/CMakeLists.txt | 12 +-- .../mythen3DetectorServer/RegisterDefs.h | 26 +++++- .../slsDetectorFunctionList.c | 83 ++++++++++++++++--- .../slsDetectorServer_defs.h | 3 +- .../slsDetectorServer_funcs.c | 7 +- slsDetectorSoftware/src/slsDetector.cpp | 12 ++- slsSupportLib/include/sls_detector_defs.h | 11 +++ 7 files changed, 129 insertions(+), 25 deletions(-) diff --git a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt index 5ae60dbb4..28dab6e51 100644 --- a/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt +++ b/slsDetectorServers/mythen3DetectorServer/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(mythen3DetectorServer +add_executable(mythen3DetectorServer_virtual slsDetectorFunctionList.c ../slsDetectorServer/slsDetectorServer.c ../slsDetectorServer/slsDetectorServer_funcs.c @@ -10,22 +10,22 @@ include_directories( ../../slsSupportLib/include ) -target_include_directories(mythen3DetectorServer +target_include_directories(mythen3DetectorServer_virtual PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) -target_compile_definitions(mythen3DetectorServer +target_compile_definitions(mythen3DetectorServer_virtual PUBLIC MYTHEN3D VIRTUAL STOP_SERVER ) -target_link_libraries(mythen3DetectorServer +target_link_libraries(mythen3DetectorServer_virtual PUBLIC pthread rt ) -set_target_properties(mythen3DetectorServer PROPERTIES +set_target_properties(mythen3DetectorServer_virtual PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) -install(TARGETS mythen3DetectorServer +install(TARGETS mythen3DetectorServer_virtual RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) diff --git a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h index ab2d110c8..94cdbf86a 100644 --- a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h +++ b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h @@ -1,3 +1,4 @@ +// stuff from Carlos #pragma once /* Definitions for FPGA*/ @@ -5,5 +6,28 @@ /* Status register */ -#define STATUS_REG (0x02 << MEM_MAP_SHIFT) +#define STATUS_REG (0x01 << MEM_MAP_SHIFT) +/* Set Cycles 64 bit register */ +#define SET_CYCLES_LSB_REG (0x02 << MEM_MAP_SHIFT) +#define SET_CYCLES_MSB_REG (0x03 << MEM_MAP_SHIFT) + +/* Set Frames 64 bit register */ +#define SET_FRAMES_LSB_REG (0x04 << MEM_MAP_SHIFT) +#define SET_FRAMES_MSB_REG (0x05 << MEM_MAP_SHIFT) + +/* Set Period 64 bit register tT = T x 50 ns */ +#define SET_PERIOD_LSB_REG (0x06 << MEM_MAP_SHIFT) +#define SET_PERIOD_MSB_REG (0x07 << MEM_MAP_SHIFT) + +/* Set Exptime 64 bit register eEXP = Exp x 25 ns */ +#define SET_EXPTIME_LSB_REG (0x08 << MEM_MAP_SHIFT) +#define SET_EXPTIME_MSB_REG (0x09 << MEM_MAP_SHIFT) + +/* Get Cycles 64 bit register */ +#define GET_CYCLES_LSB_REG (0x0A << MEM_MAP_SHIFT) +#define GET_CYCLES_MSB_REG (0x0B << MEM_MAP_SHIFT) + +/* Get Frames 64 bit register */ +#define GET_FRAMES_LSB_REG (0x0C << MEM_MAP_SHIFT) +#define GET_FRAMES_MSB_REG (0x0D << MEM_MAP_SHIFT) diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index b2d1277cd..70bea8e5e 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -190,32 +190,64 @@ int getSpeed(enum speedVariable ind) { int64_t setTimer(enum timerIndex ind, int64_t val) { + int64_t retval = -1; switch(ind){ - case FRAME_NUMBER: - + case FRAME_NUMBER: // defined in sls_detector_defs.h (general) + if(val >= 0) { + FILE_LOG(logINFO, ("Setting #frames: %lld\n",(long long int)val)); + } + retval = set64BitReg(val, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); // defined in my RegisterDefs.h + FILE_LOG(logDEBUG1, ("Getting #frames: %lld\n", (long long int)retval)); + break; + case ACQUISITION_TIME: - + if(val >= 0){ + FILE_LOG(logINFO, ("Setting exptime: %lldns\n", (long long int)val)); + val *= (1E-3 * TEMP_CLK); + } + retval = set64BitReg(val, SET_EXPTIME_LSB_REG, SET_EXPTIME_MSB_REG) / (1E-3 * TEMP_CLK); // CLK defined in slsDetectorServer_defs.h + FILE_LOG(logDEBUG1, ("Getting exptime: %lldns\n", (long long int)retval)); + break; + case FRAME_PERIOD: - + if(val >= 0){ + FILE_LOG(logINFO, ("Setting period: %lldns\n",(long long int)val)); + val *= (1E-3 * TEMP_CLK); + } + retval = set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG )/ (1E-3 * TEMP_CLK); + FILE_LOG(logDEBUG1, ("Getting period: %lldns\n", (long long int)retval)); + break; case CYCLES_NUMBER: - return -1; + if(val >= 0) { + FILE_LOG(logINFO, ("Setting #cycles: %lld\n", (long long int)val)); + } + retval = set64BitReg(val, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); + FILE_LOG(logDEBUG1, ("Getting #cycles: %lld\n", (long long int)retval)); + break; default: + FILE_LOG(logERROR, ("Timer Index not implemented for this detector: %d\n", ind)); break; } - return -1; + return retval; } int validateTimer(enum timerIndex ind, int64_t val, int64_t retval) { - + if (val < 0) + return OK; switch(ind) { case ACQUISITION_TIME: - case FRAME_PERIOD: - + // convert to freq + val *= (1E-3 * TEMP_CLK); + // convert back to timer + val = (val) / (1E-3 * TEMP_CLK); + if (val != retval) + return FAIL; + break; default: break; } @@ -227,6 +259,23 @@ int64_t getTimeLeft(enum timerIndex ind){ #ifdef VIRTUAL return 0; #endif + int64_t retval = -1; + switch(ind){ + + case FRAME_NUMBER: + retval = get64BitReg(GET_FRAMES_LSB_REG, GET_FRAMES_MSB_REG); + FILE_LOG(logINFO, ("Getting number of frames left: %lld\n",(long long int)retval)); + break; + + case CYCLES_NUMBER: + retval = get64BitReg(GET_CYCLES_LSB_REG, GET_CYCLES_MSB_REG); + FILE_LOG(logINFO, ("Getting number of cycles left: %lld\n", (long long int)retval)); + break; + + default: + FILE_LOG(logERROR, ("Remaining Timer index not implemented for this detector: %d\n", ind)); + break; + } return -1; } @@ -238,6 +287,7 @@ int startStateMachine(){ return FAIL; } FILE_LOG(logINFOBLUE, ("starting state machine\n")); + // set status to running virtual_status = 1; virtual_stop = 0; if(pthread_create(&pthread_virtual_tid, NULL, &start_timer, NULL)) { @@ -261,23 +311,30 @@ void* start_timer(void* arg) { int frameNr = 0; + // loop over number of frames for(frameNr=0; frameNr!= numFrames; ++frameNr ) { - int srcOffset = 0; - + + //check if virtual_stop is high, then break + + // sleep for exposure time struct timespec begin, end; clock_gettime(CLOCK_REALTIME, &begin); - usleep(exp_ns / 1000); - clock_gettime(CLOCK_REALTIME, &end); + + // calculate time left in period int64_t time_ns = ((end.tv_sec - begin.tv_sec) * 1E9 + (end.tv_nsec - begin.tv_nsec)); + // sleep for (period - exptime) if (periodns > time_ns) { usleep((periodns - time_ns)/ 1000); } + + // set register frames left } + // set status to idle virtual_status = 0; return NULL; } diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h index 866af52fd..1746553a2 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h @@ -8,4 +8,5 @@ /* Hardware Definitions */ #define NCHAN (128) #define NCHIP (10) -#define NDAC (16) \ No newline at end of file +#define NDAC (16) +#define TEMP_CLK (20) /* MHz */ \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c index 373eafa83..22c34dcdb 100755 --- a/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/slsDetectorServer_funcs.c @@ -18,6 +18,8 @@ const enum detectorType myDetectorType = JUNGFRAU; const enum detectorType myDetectorType = CHIPTESTBOARD; #elif MOENCHD const enum detectorType myDetectorType = MOENCH; +#elif MYTHEN3D +const enum detectorType myDetectorType = MYTHEN3; #else const enum detectorType myDetectorType = GENERIC; #endif @@ -1793,6 +1795,9 @@ int get_time_left(int file_des) { case FRAME_PERIOD: case DELAY_AFTER_TRIGGER: case CYCLES_NUMBER: +#elif MYTHEN3D + case FRAME_NUMBER: + case CYCLES_NUMBER: #endif retval = getTimeLeft(ind); FILE_LOG(logDEBUG1, ("Timer left index %d: %lld\n", ind, retval)); @@ -2228,7 +2233,7 @@ int send_update(int file_des) { if (n < 0) return printSocketReadError(); // delay -#ifndef EIGERD +#if !defined(EIGERD) && !defined(MYTHEN3D) i64 = setTimer(DELAY_AFTER_TRIGGER,GET_FLAG); n = sendData(file_des,&i64,sizeof(i64),INT64); if (n < 0) return printSocketReadError(); diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index 41c543ee2..b62503a92 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -75,6 +75,9 @@ void slsDetector::checkDetectorVersionCompatibility() { case MOENCH: arg = APIMOENCH; break; + case MYTHEN3: + arg = APIMYTHEN3; + break; default: throw NotImplementedError( "Check version compatibility is not implemented for this detector"); @@ -385,6 +388,9 @@ void slsDetector::initializeDetectorStructure(detectorType type) { case MOENCH: shm()->rxFramesPerFile = MOENCH_MAX_FRAMES_PER_FILE; break; + case MYTHEN3: + shm()->rxFramesPerFile = MYTHEN3_MAX_FRAMES_PER_FILE; + break; default: break; } @@ -739,8 +745,8 @@ void slsDetector::updateCachedDetectorVariables() { shm()->dynamicRange = i32; // settings - if ((shm()->myDetectorType != CHIPTESTBOARD) && - (shm()->myDetectorType != MOENCH)) { + if (shm()->myDetectorType == EIGER || + shm()->myDetectorType == JUNGFRAU || shm()->myDetectorType == GOTTHARD) { n += client.Receive(&i32, sizeof(i32)); shm()->currentSettings = static_cast(i32); } @@ -773,7 +779,7 @@ void slsDetector::updateCachedDetectorVariables() { shm()->timerValue[FRAME_PERIOD] = i64; // delay - if (shm()->myDetectorType != EIGER) { + if (shm()->myDetectorType != EIGER && shm()->myDetectorType != MYTHEN3 ) { n += client.Receive(&i64, sizeof(i64)); shm()->timerValue[DELAY_AFTER_TRIGGER] = i64; } diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 1116f8fb8..e4230bc4b 100755 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -63,6 +63,7 @@ #define EIGER_MAX_FRAMES_PER_FILE 10000 #define JFRAU_MAX_FRAMES_PER_FILE 10000 #define CTB_MAX_FRAMES_PER_FILE 20000 +#define MYTHEN3_MAX_FRAMES_PER_FILE 10000 #define DEFAULT_STREAMING_TIMER_IN_MS 200 @@ -1138,6 +1139,16 @@ struct detParameters { nGappixelsX = 6; nGappixelsY = 1; break; + case slsDetectorDefs::detectorType::MYTHEN3: + nChanX = 128; + nChanY = 1; + nChipX = 10; + nChipY = 1; + nDacs = 16; + dynamicRange = 16; + nGappixelsX = 0; + nGappixelsY = 0; + break; default: throw sls::RuntimeError( "Unknown detector type! " + From 170db19f48abf0c9ea6878eff09211eb678618cf Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Thu, 22 Aug 2019 15:58:32 +0200 Subject: [PATCH 4/5] initial functions for mythen3 --- slsSupportLib/include/versionAPI.h | 1 - 1 file changed, 1 deletion(-) diff --git a/slsSupportLib/include/versionAPI.h b/slsSupportLib/include/versionAPI.h index 6a31604fe..b95903c0a 100644 --- a/slsSupportLib/include/versionAPI.h +++ b/slsSupportLib/include/versionAPI.h @@ -8,5 +8,4 @@ #define APIGOTTHARD 0x190821 #define APIJUNGFRAU 0x190821 #define APIEIGER 0x190821 - #define APIMYTHEN3 0x190822 From 3ca52176b7f6fa2fe05c41405a1506437c5875f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20Fr=C3=B6jdh?= Date: Thu, 22 Aug 2019 21:21:04 +0200 Subject: [PATCH 5/5] CMake support for CTB Gui (#51) * WIP * WIP * WIP * WIP * WIP * WIP * WIP builds... * clean up * root 6.18 support --- CMakeLists.txt | 9 ++- ctbGui/CMakeLists.txt | 78 +++++++++++++++++++ .../tests/test-GeneralData.cpp | 44 +++++------ 3 files changed, 107 insertions(+), 24 deletions(-) create mode 100644 ctbGui/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index e73075393..185dc448c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.9) +cmake_minimum_required(VERSION 3.11) project(slsDetectorPackage) set(PROJECT_VERSION 5.0.0) @@ -42,7 +42,8 @@ option (SLS_USE_TESTS "TESTS" OFF) option (SLS_USE_INTEGRATION_TESTS "Integration Tests" OFF) option(SLS_USE_SANITIZER "Sanitizers for debugging" OFF) option(SLS_USE_PYTHON "Python bindings" OFF) -option(SLS_BUILD_DOCS "Documentations" OFF) +option(SLS_USE_CTBGUI "ctb GUI" OFF) +option(SLS_BUILD_DOCS "docs" OFF) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) @@ -176,6 +177,10 @@ if (SLS_USE_PYTHON) add_subdirectory(python) endif(SLS_USE_PYTHON) +if (SLS_USE_CTBGUI) + add_subdirectory(ctbGui) +endif(SLS_USE_CTBGUI) + configure_file( .clang-tidy ${CMAKE_BINARY_DIR}/.clang-tidy ) diff --git a/ctbGui/CMakeLists.txt b/ctbGui/CMakeLists.txt new file mode 100644 index 000000000..5dd2aece4 --- /dev/null +++ b/ctbGui/CMakeLists.txt @@ -0,0 +1,78 @@ + + +find_package(ROOT CONFIG REQUIRED COMPONENTS Core Gui) +find_package(TIFF REQUIRED) + +target_include_directories(ROOT::Core INTERFACE "${ROOT_INCLUDE_DIRS}") +add_library(ROOT::Flags_CXX IMPORTED INTERFACE) +separate_arguments(ROOT_CXX_FLAGS) +target_compile_options(ROOT::Flags_CXX INTERFACE ${ROOT_CXX_FLAGS}) +separate_arguments(ROOT_DEFINITIONS) +target_compile_definitions(ROOT::Flags_CXX INTERFACE ${ROOT_DEFINITIONS}) + +# This fixes a bug in the linker flags +string(REPLACE "-L " "-L" ROOT_EXE_LINKER_FLAGS "${ROOT_EXE_LINKER_FLAGS}") +separate_arguments(ROOT_EXE_LINKER_FLAGS) + +# Stuck into using old property method due to separate -L and -l arguments +# (A full path to -l is better!) +set_property(TARGET ROOT::Flags_CXX PROPERTY + INTERFACE_LINK_LIBRARIES ${ROOT_EXE_LINKER_FLAGS}) +set_property(TARGET ROOT::Core PROPERTY + INTERFACE_INCLUDE_DIRECTORIES "${ROOT_INCLUDE_DIRS}") + + +add_executable(ctbGui + ctbGui.cpp + ctbMain.cpp + ctbDacs.cpp + ctbPowers.cpp + ctbSlowAdcs.cpp + ctbSignals.cpp + ctbAdcs.cpp + ctbPattern.cpp + ctbAcquisition.cpp + ${CMAKE_SOURCE_DIR}/slsDetectorCalibration/tiffIO.cpp +) + +#TODO! Replace with target +target_include_directories(ctbGui PRIVATE + ${CMAKE_SOURCE_DIR}/slsDetectorCalibration/dataStructures + ${CMAKE_SOURCE_DIR}/slsDetectorCalibration/interpolations + ${CMAKE_SOURCE_DIR}/slsDetectorCalibration/ +) + +# Headders needed for ROOT dictionary generation +set( HEADERS + ctbMain.h + ctbDacs.h + ctbPattern.h + ctbSignals.h + ctbAdcs.h + ctbAcquisition.h + ctbPowers.h + ctbSlowAdcs.h +) + +#set(ROOT_INCLUDE_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +# ROOT dictionary generation +include("${ROOT_DIR}/modules/RootNewMacros.cmake") +root_generate_dictionary(ctbDict ${HEADERS} LINKDEF ctbLinkDef.h) +add_library(ctbRootLib SHARED ctbDict.cxx) +target_include_directories(ctbRootLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_link_libraries(ctbRootLib PUBLIC + ROOT::Core + ${ROOT_LIBRARIES} + ${ROOT_EXE_LINKER_FLAGS} +) + +target_link_libraries(ctbGui PUBLIC + slsDetectorShared + ctbRootLib + ${TIFF_LIBRARIES} +) + +set_target_properties(ctbGui PROPERTIES + RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin +) \ No newline at end of file diff --git a/slsReceiverSoftware/tests/test-GeneralData.cpp b/slsReceiverSoftware/tests/test-GeneralData.cpp index df0713469..3d76f5ca1 100755 --- a/slsReceiverSoftware/tests/test-GeneralData.cpp +++ b/slsReceiverSoftware/tests/test-GeneralData.cpp @@ -55,29 +55,29 @@ // CHECK(subFrameNumber == -1); // } -TEST_CASE("Parse header gotthard data", "[receiver]") { - GotthardData data; - struct packet { - uint32_t frameNumber; - unsigned char data[GOTTHARD_PACKET_SIZE]; - } __attribute__((packed)); - packet test_packet; - test_packet.frameNumber = 25698u; +// TEST_CASE("Parse header gotthard data", "[receiver]") { +// GotthardData data; +// struct packet { +// uint32_t frameNumber; +// unsigned char data[GOTTHARD_PACKET_SIZE]; +// } __attribute__((packed)); +// packet test_packet; +// test_packet.frameNumber = 25698u; - int index = 0; - char *packetData = reinterpret_cast(&test_packet); - uint32_t dynamicRange{0}; - bool oddStartingPacket{0}; - uint64_t frameNumber{0}; - uint32_t packetNumber{0}; - uint32_t subFrameNumber{0}; - uint64_t bunchId{0}; +// int index = 0; +// char *packetData = reinterpret_cast(&test_packet); +// uint32_t dynamicRange{0}; +// bool oddStartingPacket{0}; +// uint64_t frameNumber{0}; +// uint32_t packetNumber{0}; +// uint32_t subFrameNumber{0}; +// uint64_t bunchId{0}; - data.GetHeaderInfo(index, packetData, dynamicRange, oddStartingPacket, - frameNumber, packetNumber, subFrameNumber, bunchId); +// data.GetHeaderInfo(index, packetData, dynamicRange, oddStartingPacket, +// frameNumber, packetNumber, subFrameNumber, bunchId); - CHECK(frameNumber == test_packet.frameNumber/2); - CHECK(subFrameNumber == -1); - CHECK(bunchId == -1); +// CHECK(frameNumber == test_packet.frameNumber/2); +// CHECK(subFrameNumber == -1); +// CHECK(bunchId == -1); -} \ No newline at end of file +// } \ No newline at end of file