diff --git a/RELEASE.txt b/RELEASE.txt index 035deeca5..992735198 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -31,7 +31,7 @@ This document describes the differences between v7.0.0 and v6.x.x - rx_arping - rx_threadsids max is now 9 (breaking api) - fixed datastream disabling for eiger. Its only available in 10g mode. -- m3 server crash (vthrehsold) +- m3 server crash (vthrehsold dac names were not provided) - allow vtrim to be interpolated for Eiger settings - m3 setThresholdEnergy and setAllThresholdEnergy was overwriting gaincaps with settings enum - can set localhost with virtual server with minimum configuration: (hostname localhost, rx_hostname localhost, udp_dstip auto) @@ -41,6 +41,10 @@ This document describes the differences between v7.0.0 and v6.x.x - file write disabled by default - eiger 12 bit mode - start non blocking acquisition at modular level +- connect master commands to api (allow set master for eiger) +--ignore-config command line +- command line argument 'master' mainly for virtual servers (also master/top for real eiger), only one virtual server for eiger, use command lines for master/top +- stop servers also check for errors at startup( in case it was running with an older version) - hostname cmd failed when connecting to servers in update mode (ctb, moench, jungfrau, eiger) - missingpackets signed (negative => extra packets) diff --git a/python/scripts/generate_functions.py b/python/scripts/generate_functions.py index 242cd2bb3..bf943330a 100644 --- a/python/scripts/generate_functions.py +++ b/python/scripts/generate_functions.py @@ -11,9 +11,17 @@ manually from clang import cindex import subprocess import argparse +import sys +from parse import system_include_paths, clang_format_version + +required_version = 13 +RED = '\033[91m' +ENDC = '\033[0m' +if (ver := clang_format_version()) != required_version: + print(f'{RED}Clang format version {required_version} required, detected: {ver}. Bye!{ENDC}') + sys.exit(1) -from parse import system_include_paths default_build_path = "/home/l_frojdh/sls/build/" fpath = "../../slsDetectorSoftware/src/Detector.cpp" @@ -66,7 +74,7 @@ def get_arguments_with_default(node): args = [] for arg in node.get_arguments(): tokens = [t.spelling for t in arg.get_tokens()] - print(tokens) + # print(tokens) if '=' in tokens: if arg.type.spelling == "sls::Positions": #TODO! automate args.append("py::arg() = Positions{}") @@ -111,19 +119,11 @@ def visit(node): lines.append( f'.def("{child.spelling}",{fs} &Detector::{child.spelling}{args})' ) + print(f'&Detector::{child.spelling}{args})') cn.append(child) for child in node.get_children(): visit(child) - # .def("setRxHostname", - # (void (Detector::*)(const std::string &, Positions)) & - # Detector::setRxHostname, - # py::arg(), py::arg() = Positions{}) - # .def("setRxHostname", - # (void (Detector::*)(const std::vector &)) & - # Detector::setRxHostname, - # py::arg()) - visit(tu.cursor) diff --git a/python/scripts/parse.py b/python/scripts/parse.py index 310a6af36..19dd8d4d3 100644 --- a/python/scripts/parse.py +++ b/python/scripts/parse.py @@ -5,6 +5,12 @@ import subprocess from subprocess import PIPE import os +def clang_format_version(): + p = subprocess.run(['clang-format', '--version'], capture_output = True) + ver = p.stdout.decode().split()[2] + major = int(ver.split('.')[0]) + return major + def remove_comments(text): def replacer(match): diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 6c4b200db..e8aff9479 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -1474,6 +1474,19 @@ class Detector(CppDetectorApi): def trimval(self, value): ut.set_using_dict(self.setAllTrimbits, value) + @property + @element + def master(self): + """ + [Eiger] Sets half module to master and others to slaves.\n + [Gotthard][Gotthard2][Mythen3][Eiger] Gets if the current module/ half module is master. + """ + return self.getMaster() + + @master.setter + def master(self, value): + ut.set_using_dict(self.setMaster, value) + @property @element def lock(self): @@ -2126,6 +2139,21 @@ class Detector(CppDetectorApi): """ return ut.reduce_time(self.getMeasuredSubFramePeriod()) + @property + @element + def top(self): + """[Eiger] Sets half module to top (1), else bottom. + + Note + ----- + Advanced Function! + """ + return self.getTop() + + @top.setter + def top(self, value): + ut.set_using_dict(self.setTop, value) + """ ------------------<<>>------------------------- """ diff --git a/python/src/detector.cpp b/python/src/detector.cpp index f796c3cbe..c6cd4927b 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1,8 +1,8 @@ -// SPDX-License-Identifier: LGPL-3.0-or-other -// Copyright (C) 2021 Contributors to the SLS Detector Package /* WARINING This file is auto generated any edits might be overwritten without * warning */ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package #include #include #include @@ -173,6 +173,12 @@ void init_det(py::module &m) { .def("setFlipRows", (void (Detector::*)(bool, sls::Positions)) & Detector::setFlipRows, py::arg(), py::arg() = Positions{}) + .def("getMaster", + (Result(Detector::*)(sls::Positions) const) & + Detector::getMaster, + py::arg() = Positions{}) + .def("setMaster", (void (Detector::*)(bool, int)) & Detector::setMaster, + py::arg(), py::arg()) .def("isVirtualDetectorServer", (Result(Detector::*)(sls::Positions) const) & Detector::isVirtualDetectorServer, @@ -766,7 +772,7 @@ void init_det(py::module &m) { Detector::getRxLastClientIP, py::arg() = Positions{}) .def("getRxThreadIds", - (Result>(Detector::*)(sls::Positions) const) & + (Result>(Detector::*)(sls::Positions) const) & Detector::getRxThreadIds, py::arg() = Positions{}) .def("getRxArping", @@ -1005,6 +1011,13 @@ void init_det(py::module &m) { sls::Positions)) & Detector::setDataStream, py::arg(), py::arg(), py::arg() = Positions{}) + .def("getTop", + (Result(Detector::*)(sls::Positions) const) & + Detector::getTop, + py::arg() = Positions{}) + .def("setTop", + (void (Detector::*)(bool, sls::Positions)) & Detector::setTop, + py::arg(), py::arg() = Positions{}) .def("getChipVersion", (Result(Detector::*)(sls::Positions) const) & Detector::getChipVersion, @@ -1263,10 +1276,6 @@ void init_det(py::module &m) { (Result>(Detector::*)(sls::Positions) const) & Detector::getGateDelayForAllGates, py::arg() = Positions{}) - .def("getMaster", - (Result(Detector::*)(sls::Positions) const) & - Detector::getMaster, - py::arg() = Positions{}) .def("getChipStatusRegister", (Result(Detector::*)(sls::Positions) const) & Detector::getChipStatusRegister, @@ -1555,7 +1564,7 @@ void init_det(py::module &m) { Detector::getUpdateMode, py::arg() = Positions{}) .def("setUpdateMode", - (void (Detector::*)(bool, sls::Positions)) & + (void (Detector::*)(const bool, sls::Positions)) & Detector::setUpdateMode, py::arg(), py::arg() = Positions{}) .def("readRegister", diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index cc425b2bb..853927404 100755 Binary files a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer and b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer differ diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 40217eb41..06db979c0 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -433,16 +433,21 @@ void initControlServer() { } void initStopServer() { - - usleep(CTRL_SRVR_INIT_TIME_US); - if (mapCSP0() == FAIL) { - LOG(logERROR, - ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); - exit(EXIT_FAILURE); - } + if (!updateFlag && initError == OK) { + usleep(CTRL_SRVR_INIT_TIME_US); + if (mapCSP0() == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, + "Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + return; + } #ifdef VIRTUAL - sharedMemory_setStop(0); + sharedMemory_setStop(0); #endif + } + initCheckDone = 1; } /* set up detector */ diff --git a/slsDetectorServers/eigerDetectorServer/Beb.c b/slsDetectorServers/eigerDetectorServer/Beb.c index e9f1ad42c..1cbb41833 100644 --- a/slsDetectorServers/eigerDetectorServer/Beb.c +++ b/slsDetectorServers/eigerDetectorServer/Beb.c @@ -177,7 +177,7 @@ void Beb_AdjustIPChecksum(struct udp_header_type *ip) { ip->ip_header_checksum[1] = ip_checksum & 0xff; } -void Beb_GetModuleConfiguration(int *master, int *top, int *normal) { +int Beb_GetModuleConfiguration(int *master, int *top, int *normal) { *top = 0; *master = 0; // mapping new memory to read master top module configuration @@ -187,6 +187,7 @@ void Beb_GetModuleConfiguration(int *master, int *top, int *normal) { int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR); if (fd < 0) { LOG(logERROR, ("Module Configuration FAIL\n")); + return FAIL; } else { // read data ret = Beb_Read32(csp0base, BEB_CONFIG_RD_OFST); @@ -202,6 +203,7 @@ void Beb_GetModuleConfiguration(int *master, int *top, int *normal) { // close file pointer Beb_close(fd, csp0base); } + return OK; } int Beb_IsTransmitting(int *retval, int tengiga, int waitForDelay) { diff --git a/slsDetectorServers/eigerDetectorServer/Beb.h b/slsDetectorServers/eigerDetectorServer/Beb.h index a238c1529..ab84584ea 100644 --- a/slsDetectorServers/eigerDetectorServer/Beb.h +++ b/slsDetectorServers/eigerDetectorServer/Beb.h @@ -15,7 +15,7 @@ int Beb_SetHeaderData(uint64_t src_mac, uint32_t src_ip, uint16_t src_port, uint64_t dst_mac, uint32_t dst_ip, uint16_t dst_port); void Beb_AdjustIPChecksum(struct udp_header_type *ip); -void Beb_GetModuleConfiguration(int *master, int *top, int *normal); +int Beb_GetModuleConfiguration(int *master, int *top, int *normal); int Beb_IsTransmitting(int *retval, int tengiga, int waitForDelay); void Beb_SetTopVariable(int val); diff --git a/slsDetectorServers/eigerDetectorServer/CMakeLists.txt b/slsDetectorServers/eigerDetectorServer/CMakeLists.txt index ae8b9b0ea..39f0aea23 100644 --- a/slsDetectorServers/eigerDetectorServer/CMakeLists.txt +++ b/slsDetectorServers/eigerDetectorServer/CMakeLists.txt @@ -16,91 +16,31 @@ include_directories( ../../slsSupportLib/include ) -add_executable(eigerDetectorServerMaster_virtual +add_executable(eigerDetectorServer_virtual ${src} ) -target_include_directories(eigerDetectorServerMaster_virtual +target_include_directories(eigerDetectorServer_virtual PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) -target_compile_definitions(eigerDetectorServerMaster_virtual - PUBLIC EIGERD PCCOMPILE STOP_SERVER - PUBLIC VIRTUAL #VIRTUAL_9M - PUBLIC VIRTUAL_MASTER -) - -target_link_libraries(eigerDetectorServerMaster_virtual - PUBLIC pthread rt slsProjectCSettings -) - -set_target_properties(eigerDetectorServerMaster_virtual PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) - -install(TARGETS eigerDetectorServerMaster_virtual - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - - - - - -add_executable(eigerDetectorServerSlaveTop_virtual - ${src} -) - -target_include_directories(eigerDetectorServerSlaveTop_virtual - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(eigerDetectorServerSlaveTop_virtual - PUBLIC EIGERD PCCOMPILE STOP_SERVER - PUBLIC VIRTUAL #VIRTUAL_9M - PUBLIC VIRTUAL_TOP -) - -target_link_libraries(eigerDetectorServerSlaveTop_virtual - PUBLIC pthread rt slsProjectCSettings -) - -set_target_properties(eigerDetectorServerSlaveTop_virtual PROPERTIES - RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin -) - -install(TARGETS eigerDetectorServerSlaveTop_virtual - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} -) - - - - -add_executable(eigerDetectorServerSlaveBottom_virtual - ${src} -) - -target_include_directories(eigerDetectorServerSlaveBottom_virtual - PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} -) - -target_compile_definitions(eigerDetectorServerSlaveBottom_virtual +target_compile_definitions(eigerDetectorServer_virtual PUBLIC EIGERD PCCOMPILE STOP_SERVER PUBLIC VIRTUAL #VIRTUAL_9M ) -target_link_libraries(eigerDetectorServerSlaveBottom_virtual +target_link_libraries(eigerDetectorServer_virtual PUBLIC pthread rt slsProjectCSettings ) -set_target_properties(eigerDetectorServerSlaveBottom_virtual PROPERTIES +set_target_properties(eigerDetectorServer_virtual PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) -install(TARGETS eigerDetectorServerSlaveBottom_virtual +install(TARGETS eigerDetectorServer_virtual RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) - configure_file(config_eiger.txt ${CMAKE_BINARY_DIR}/bin/config_eiger.txt COPYONLY) configure_file(detid_eiger.txt ${CMAKE_BINARY_DIR}/bin/detid_eiger.txt COPYONLY) diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.c b/slsDetectorServers/eigerDetectorServer/FebControl.c index 5aba2ecf7..24097cfb1 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.c +++ b/slsDetectorServers/eigerDetectorServer/FebControl.c @@ -18,7 +18,7 @@ const unsigned int Feb_Control_leftAddress = 0x100; const unsigned int Feb_Control_rightAddress = 0x200; -int Feb_Control_master = 0; +int Feb_Control_master = -1; int Feb_Control_normal = 0; int Feb_Control_activated = 1; @@ -50,17 +50,16 @@ double ratemax = -1; // setup void Feb_Control_activate(int activate) { Feb_Control_activated = activate; } -void Feb_Control_FebControl() { - Feb_Control_staticBits = Feb_Control_acquireNReadoutMode = - Feb_Control_triggerMode = Feb_Control_externalEnableMode = - Feb_Control_subFrameMode = 0; +int Feb_Control_FebControl(int normal) { + Feb_Control_staticBits = 0; + Feb_Control_acquireNReadoutMode = 0; + Feb_Control_triggerMode = 0; + Feb_Control_externalEnableMode = 0; + Feb_Control_subFrameMode = 0; Feb_Control_trimbit_size = 263680; Feb_Control_last_downloaded_trimbits = malloc(Feb_Control_trimbit_size * sizeof(int)); -} -int Feb_Control_Init(int master, int normal) { - Feb_Control_master = master; Feb_Control_normal = normal; Feb_Interface_SetAddress(Feb_Control_rightAddress, Feb_Control_leftAddress); if (Feb_Control_activated) { @@ -1556,9 +1555,8 @@ int Feb_Control_SetTop(enum TOPINDEX ind, int left, int right) { return 1; } -void Feb_Control_SetMasterVariable(int val) { Feb_Control_master = val; } - int Feb_Control_SetMaster(enum MASTERINDEX ind) { + uint32_t offset = DAQ_REG_HRDWRE; unsigned int addr[2] = {Feb_Control_leftAddress, Feb_Control_rightAddress}; char *master_names[] = {MASTER_NAMES}; @@ -1595,9 +1593,31 @@ int Feb_Control_SetMaster(enum MASTERINDEX ind) { LOG(logINFOBLUE, ("%s Master flag to %s Feb\n", (ind == MASTER_HARDWARE ? "Resetting" : "Overwriting"), master_names[ind])); + return 1; } +int Feb_Control_SetMasterEffects(int master, int controlServer) { + int prevMaster = Feb_Control_master; + + Feb_Control_master = master; + // change in master for 9m + if (controlServer && prevMaster != Feb_Control_master && + !Feb_Control_normal) { + if (prevMaster) { + Feb_Control_CloseSerialCommunication(); + } + if (Feb_Control_master) { + if (!Feb_Control_OpenSerialCommunication()) { + LOG(logERROR, ("Could not intitalize feb control serial " + "communication\n")); + return FAIL; + } + } + } + return OK; +} + int Feb_Control_SetQuad(int val) { LOG(logINFO, ("Setting Quad to %d in Feb\n", val)); Feb_Control_quadMode = val; diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.h b/slsDetectorServers/eigerDetectorServer/FebControl.h index 56a68024b..325c4af44 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.h +++ b/slsDetectorServers/eigerDetectorServer/FebControl.h @@ -7,8 +7,7 @@ // setup void Feb_Control_activate(int activate); -void Feb_Control_FebControl(); -int Feb_Control_Init(int master, int normal); +int Feb_Control_FebControl(int normal); int Feb_Control_OpenSerialCommunication(); void Feb_Control_CloseSerialCommunication(); int Feb_Control_CheckSetup(); @@ -88,8 +87,8 @@ int Feb_Control_Get_Counter_Bit(); int Feb_Control_SetInterruptSubframe(int val); int Feb_Control_GetInterruptSubframe(); int Feb_Control_SetTop(enum TOPINDEX ind, int left, int right); -void Feb_Control_SetMasterVariable(int val); int Feb_Control_SetMaster(enum MASTERINDEX ind); +int Feb_Control_SetMasterEffects(int master, int controlServer); int Feb_Control_SetQuad(int val); int Feb_Control_SetChipSignalsToTrimQuad(int enable); int Feb_Control_SetReadNRows(int value); diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index e2f73123c..ff50e6e8f 100755 Binary files a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer and b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer differ diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index 11e72443f..f73e44ecd 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -26,12 +26,17 @@ extern int updateFlag; extern udpStruct udpDetails[MAX_UDP_DESTINATION]; extern int numUdpDestinations; extern const enum detectorType myDetectorType; +extern int ignoreConfigFileFlag; // Global variable from communication_funcs.c extern int isControlServer; extern void getMacAddressinString(char *cmac, int size, uint64_t mac); extern void getIpAddressinString(char *cip, uint32_t ip); +// Variables that will be exported +int masterCommandLine = -1; +int topCommandLine = -1; + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -226,6 +231,23 @@ int getModuleId(int *ret, char *mess) { return getModuleIdInFile(ret, mess, ID_FILE); } +int updateModuleId() { + int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE); + if (initError == FAIL) { + return FAIL; + } +#ifdef VIRTUAL + eiger_virtual_module_id = modid; +#else + if (Beb_SetModuleId(modid) == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, ("Could not get module id from the file")); + return FAIL; + } +#endif + return OK; +} + u_int64_t getDetectorMAC() { char mac[255] = ""; u_int64_t res = 0; @@ -305,46 +327,36 @@ u_int32_t getDetectorIP() { void initControlServer() { LOG(logINFOBLUE, ("Configuring Control server\n")); if (!updateFlag && initError == OK) { - int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE); -#ifdef VIRTUAL - eiger_virtual_module_id = modid; -#endif - if (initError == FAIL) { + if (updateModuleConfiguration() == FAIL) { + initCheckDone = 1; return; } - getModuleConfiguration(); #ifndef VIRTUAL sharedMemory_lockLocalLink(); - Feb_Control_SetMasterVariable(master); Feb_Interface_FebInterface(); - Feb_Control_FebControl(); - // same addresses for top and bottom - if (!Feb_Control_Init(master, normal)) { + if (!Feb_Control_FebControl(normal)) { initError = FAIL; - sprintf(initErrorMessage, "Could not intitalize feb control\n"); + sprintf(initErrorMessage, + "Could not intitalize eiger detector sever: feb control\n"); LOG(logERROR, (initErrorMessage)); initCheckDone = 1; sharedMemory_unlockLocalLink(); return; } - // master of 9M, check high voltage serial communication to blackfin - if (master && !normal) { - if (!Feb_Control_OpenSerialCommunication()) { - initError = FAIL; - sprintf( - initErrorMessage, - "Could not intitalize feb control serial communication\n"); - LOG(logERROR, (initErrorMessage)); - initCheckDone = 1; - sharedMemory_unlockLocalLink(); - return; - } + if (Feb_Control_SetMasterEffects(master, isControlServer) == FAIL) { + initError = FAIL; + sprintf(initErrorMessage, "Could not intitalize HV for eiger " + "detector server: feb control serial " + "communication\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + sharedMemory_unlockLocalLink(); + return; } sharedMemory_unlockLocalLink(); LOG(logDEBUG1, ("Control server: FEB Initialization done\n")); Beb_SetTopVariable(top); Beb_Beb(); - Beb_SetModuleId(modid); LOG(logDEBUG1, ("Control server: BEB Initialization done\n")); #endif // also reads config file and deactivates @@ -354,73 +366,126 @@ void initControlServer() { } void initStopServer() { + if (!updateFlag && initError == OK) { + // wait a few s (control server is setting top/master from config file/ + // command line) + usleep(WAIT_STOP_SERVER_START); + LOG(logINFOBLUE, ("Configuring Stop server\n")); + if (updateModuleConfiguration() == FAIL) { + initCheckDone = 1; + return; + } #ifdef VIRTUAL - LOG(logINFOBLUE, ("Configuring Stop server\n")); - getModuleConfiguration(); - sharedMemory_setStop(0); - // get top/master in virtual - readConfigFile(); + sharedMemory_setStop(0); + // force top or master if in config file + if (readConfigFile() == FAIL) { + initCheckDone = 1; + return; + } + // force top or master if in command line + if (checkCommandLineConfiguration() == FAIL) { + initCheckDone = 1; + return; + } #else - // wait a few s (control server is setting top/master from config file) - usleep(WAIT_STOP_SERVER_START); - LOG(logINFOBLUE, ("Configuring Stop server\n")); - // exit(-1); - getModuleConfiguration(); - sharedMemory_lockLocalLink(); - Feb_Control_SetMasterVariable(master); - Feb_Interface_FebInterface(); - Feb_Control_FebControl(); - // same addresses for top and bottom - Feb_Control_Init(master, normal); - sharedMemory_unlockLocalLink(); - LOG(logDEBUG1, ("Stop server: FEB Initialization done\n")); + // control server read config file and already set up master/top + sharedMemory_lockLocalLink(); + Feb_Interface_FebInterface(); + if (!Feb_Control_FebControl(normal)) { + initError = FAIL; + sprintf(initErrorMessage, "Could not intitalize feb control\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + sharedMemory_unlockLocalLink(); + return; + } + if (Feb_Control_SetMasterEffects(master, isControlServer) == FAIL) { + initError = FAIL; + sprintf(initErrorMessage, "Could not intitalize HV for eiger " + "detector server: feb control serial " + "communication\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + sharedMemory_unlockLocalLink(); + return; + } + sharedMemory_unlockLocalLink(); + LOG(logDEBUG1, ("Stop server: FEB Initialization done\n")); + Beb_SetTopVariable(top); + Beb_Beb(); + LOG(logDEBUG1, ("Control server: BEB Initialization done\n")); #endif - // client first connect (from shm) will activate - if (setActivate(0) == FAIL) { - LOG(logERROR, ("Could not deactivate in stop server\n")); + // client first connect (from shm) will activate + if (setActivate(0) == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, "Could not deactivate\n"); + LOG(logERROR, (initErrorMessage)); + } } + initCheckDone = 1; } -void getModuleConfiguration() { - if (initError == FAIL) { - return; - } +void checkVirtual9MFlag() { #ifdef VIRTUAL -#ifdef VIRTUAL_MASTER - master = 1; - top = 1; -#else - master = 0; -#ifdef VIRTUAL_TOP - top = 1; -#else - top = 0; -#endif -#endif - #ifdef VIRTUAL_9M normal = 0; #else normal = 1; #endif +#endif +} -#else - Beb_GetModuleConfiguration(&master, &top, &normal); +int updateModuleConfiguration() { + if (getModuleConfiguration(&master, &top, &normal) == FAIL) { + return FAIL; + } +#ifdef VIRTUAL + checkVirtual9MFlag(); #endif if (isControlServer) { LOG(logINFOBLUE, ("Module: %s %s %s\n", (top ? "TOP" : "BOTTOM"), (master ? "MASTER" : "SLAVE"), (normal ? "NORMAL" : "SPECIAL"))); } + return OK; +} + +int getModuleConfiguration(int *m, int *t, int *n) { + if (initError == FAIL) { + return FAIL; + } +#ifdef VIRTUAL + *m = master; + *t = top; + *n = normal; +#else + if (Beb_GetModuleConfiguration(m, t, n) == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, ("Could not get module configuration\n")); + LOG(logERROR, (initErrorMessage)); + return FAIL; + } +#endif + LOG(logDEBUG, + ("module config read: master:%d top:%d normal:%d\n", *m, *t, *n)); + return OK; } int readConfigFile() { - if (initError == FAIL) { return initError; } - master = -1; + + if (ignoreConfigFileFlag) { + LOG(logWARNING, ("Ignoring Config file\n")); + return OK; + } + +#ifndef VIRTUAL + // if not found in config file, they will be reset to hardware settings top = -1; + master = -1; +#endif const int fileNameSize = 128; char fname[fileNameSize]; @@ -471,91 +536,54 @@ int readConfigFile() { // top command if (!strncmp(line, "top", strlen("top"))) { + int t = -1; // cannot scan values - if (sscanf(line, "%s %d", command, &top) != 2) { + if (sscanf(line, "%s %d", command, &t) != 2) { sprintf(initErrorMessage, "Could not scan top commands from on-board server " "config file. Line:[%s].\n", line); break; } -#ifndef VIRTUAL - enum TOPINDEX ind = (top == 1 ? OW_TOP : OW_BOTTOM); - if (!Beb_SetTop(ind)) { - sprintf( - initErrorMessage, - "Could not overwrite top to %d in Beb from on-board server " - "config file. Line:[%s].\n", - top, line); + if (t != 0 && t != 1) { + sprintf(initErrorMessage, + "Invalid top argument from on-board server " + "config file. Line:[%s].\n", + line); break; } - sharedMemory_lockLocalLink(); - if (!Feb_Control_SetTop(ind, 1, 1)) { - sprintf( - initErrorMessage, - "Could not overwrite top to %d in Feb from on-board server " - "config file. Line:[%s].\n", - top, line); - sharedMemory_unlockLocalLink(); + if (setTop(t == 1 ? OW_TOP : OW_BOTTOM) == FAIL) { + sprintf(initErrorMessage, + "Could not set top from config file. Line:[%s].\n", + line); break; } - sharedMemory_unlockLocalLink(); - // validate change - int actual_top = -1, temp = -1, temp2 = -1; - Beb_GetModuleConfiguration(&temp, &actual_top, &temp2); - if (actual_top != top) { - sprintf(initErrorMessage, "Could not set top to %d. Read %d\n", - top, actual_top); - break; - } - Beb_SetTopVariable(top); -#endif } // master command else if (!strncmp(line, "master", strlen("master"))) { + int m = -1; // cannot scan values - if (sscanf(line, "%s %d", command, &master) != 2) { + if (sscanf(line, "%s %d", command, &m) != 2) { sprintf(initErrorMessage, "Could not scan master commands from on-board server " "config file. Line:[%s].\n", line); break; } -#ifndef VIRTUAL - enum MASTERINDEX ind = (master == 1 ? OW_MASTER : OW_SLAVE); - if (!Beb_SetMaster(ind)) { + if (m != 0 && m != 1) { sprintf(initErrorMessage, - "Could not overwrite master to %d in Beb from on-board " - "server " + "Invalid master argument from on-board server " "config file. Line:[%s].\n", - master, line); + line); break; } - sharedMemory_lockLocalLink(); - if (!Feb_Control_SetMaster(ind)) { + if (setMaster(m == 1 ? OW_MASTER : OW_SLAVE) == FAIL) { sprintf(initErrorMessage, - "Could not overwrite master to %d in Feb from on-board " - "server " - "config file. Line:[%s].\n", - master, line); - sharedMemory_unlockLocalLink(); + "Could not set master from config file. Line:[%s].\n", + line); break; } - sharedMemory_unlockLocalLink(); - // validate change - int actual_master = -1, temp = -1, temp2 = -1; - Beb_GetModuleConfiguration(&actual_master, &temp, &temp2); - if (actual_master != master) { - sprintf(initErrorMessage, - "Could not set master to %d. Read %d\n", master, - actual_master); - break; - } - sharedMemory_lockLocalLink(); - Feb_Control_SetMasterVariable(master); - sharedMemory_unlockLocalLink(); -#endif } // other commands @@ -576,8 +604,10 @@ int readConfigFile() { LOG(logINFO, ("Successfully read config file\n")); } +#ifndef VIRTUAL // reset to hardware settings if not in config file (if overwritten) resetToHardwareSettings(); +#endif return initError; } @@ -589,55 +619,56 @@ void resetToHardwareSettings() { } // top not set in config file if (top == -1) { - if (!Beb_SetTop(TOP_HARDWARE)) { + LOG(logINFO, ("Resetting Top to hardware settings\n")); + if (setTop(TOP_HARDWARE) == FAIL) { initError = FAIL; strcpy(initErrorMessage, - "Could not reset Top flag to Beb hardware settings.\n"); + "Could not reset Top flag to hardware settings.\n"); LOG(logERROR, ("%s\n\n", initErrorMessage)); return; } - sharedMemory_lockLocalLink(); - if (!Feb_Control_SetTop(TOP_HARDWARE, 1, 1)) { - initError = FAIL; - strcpy(initErrorMessage, - "Could not reset Top flag to Feb hardware settings.\n"); - LOG(logERROR, ("%s\n\n", initErrorMessage)); - sharedMemory_unlockLocalLink(); - return; - } - sharedMemory_unlockLocalLink(); - int temp = -1, temp2 = -1; - Beb_GetModuleConfiguration(&temp, &top, &temp2); - Beb_SetTopVariable(top); } // master not set in config file if (master == -1) { - if (!Beb_SetMaster(TOP_HARDWARE)) { + LOG(logINFO, ("Resetting Master to hardware settings\n")); + if (setMaster(MASTER_HARDWARE) == FAIL) { initError = FAIL; strcpy(initErrorMessage, - "Could not reset Master flag to Beb hardware settings.\n"); + "Could not reset Master flag to hardware settings.\n"); LOG(logERROR, ("%s\n\n", initErrorMessage)); return; } - sharedMemory_lockLocalLink(); - if (!Feb_Control_SetMaster(TOP_HARDWARE)) { - initError = FAIL; - strcpy(initErrorMessage, - "Could not reset Master flag to Feb hardware settings.\n"); - LOG(logERROR, ("%s\n\n", initErrorMessage)); - sharedMemory_unlockLocalLink(); - return; - } - sharedMemory_unlockLocalLink(); - int temp = -1, temp2 = -1; - Beb_GetModuleConfiguration(&master, &temp, &temp2); - sharedMemory_lockLocalLink(); - Feb_Control_SetMasterVariable(master); - sharedMemory_unlockLocalLink(); } #endif } +int checkCommandLineConfiguration() { + if (masterCommandLine != -1) { + LOG(logINFO, ("Setting %s from Command Line\n", + (masterCommandLine == 1 ? "Master" : "Slave"))); + if (setMaster(masterCommandLine == 1 ? OW_MASTER : OW_SLAVE) == FAIL) { + initError = FAIL; + sprintf(initErrorMessage, "Could not set %s from command line.\n", + (masterCommandLine == 1 ? "Master" : "Slave")); + LOG(logERROR, (initErrorMessage)); + return FAIL; + } + } + + if (topCommandLine != -1) { + LOG(logINFO, ("Setting %s from Command Line\n", + (topCommandLine == 1 ? "Top" : "Bottom"))); + if (setTop(topCommandLine == 1 ? OW_TOP : OW_BOTTOM) == FAIL) { + initError = FAIL; + sprintf(initErrorMessage, "Could not set %s from command line.\n", + (topCommandLine == 1 ? "Top" : "Bottom")); + LOG(logERROR, (initErrorMessage)); + return FAIL; + } + } + return OK; +} + /* set up detector */ void allocateDetectorStructureMemory() { @@ -671,15 +702,29 @@ void allocateDetectorStructureMemory() { } void setupDetector() { - allocateDetectorStructureMemory(); + + // force top or master if in config file + if (readConfigFile() == FAIL) + return; + // force top or master if in command line + if (checkCommandLineConfiguration() == FAIL) + return; + + LOG(logINFOBLUE, + ("Module: %s %s %s\n", (top ? "TOP" : "BOTTOM"), + (master ? "MASTER" : "SLAVE"), (normal ? "NORMAL" : "SPECIAL"))); + + if (updateModuleId() == FAIL) + return; + + LOG(logINFOBLUE, ("Setting Default Parameters\n")); resetToDefaultDacs(0); #ifdef VIRTUAL sharedMemory_setStatus(IDLE); setupUDPCommParameters(); #endif - LOG(logINFOBLUE, ("Setting Default Parameters\n")); // setting default measurement parameters setNumFrames(DEFAULT_NUM_FRAMES); setExpTime(DEFAULT_EXPTIME); @@ -719,14 +764,6 @@ void setupDetector() { } sharedMemory_unlockLocalLink(); #endif - // force top or master if in config file - if (readConfigFile() == FAIL) { - return; - } - LOG(logINFOBLUE, - ("Module: %s %s %s\n", (top ? "TOP" : "BOTTOM"), - (master ? "MASTER" : "SLAVE"), (normal ? "NORMAL" : "SPECIAL"))); - if (setNumberofDestinations(numUdpDestinations) == FAIL) { initError = FAIL; strcpy(initErrorMessage, "Could not set number of udp destinations\n"); @@ -1462,7 +1499,120 @@ int setHighVoltage(int val) { /* parameters - timing, extsig */ -int isMaster() { return master; } +int setMaster(enum MASTERINDEX m) { + char *master_names[] = {MASTER_NAMES}; + LOG(logINFOBLUE, ("Setting up Master flag as %s\n", master_names[m])); +#ifdef VIRTUAL + switch (m) { + case OW_MASTER: + master = 1; + break; + case OW_SLAVE: + master = 0; + break; + default: + // hardware settings (do nothing) + break; + } +#else + // need to set it only once via the control server + if (isControlServer) { + if (!Beb_SetMaster(m)) { + return FAIL; + } + + sharedMemory_lockLocalLink(); + if (!Feb_Control_SetMaster(m)) { + sharedMemory_unlockLocalLink(); + return FAIL; + } + sharedMemory_unlockLocalLink(); + } + + // get and update master variable (cannot get from m, could be hardware) + if (isMaster(&master) == FAIL) { + return FAIL; + } + // verify for master and slave (not hardware) + if ((m == OW_MASTER && master == 0) || (m == OW_SLAVE && master == 1)) { + LOG(logERROR, + ("could not set master/slave. Master value retrieved %d\n", + master)); + return FAIL; + } + + // feb variable and hv comms (9m) + sharedMemory_lockLocalLink(); + if (Feb_Control_SetMasterEffects(master, isControlServer) == FAIL) { + sharedMemory_unlockLocalLink(); + return FAIL; + } + sharedMemory_unlockLocalLink(); +#endif + return OK; +} + +int isMaster(int *retval) { + int m = -1, t = -1, n = -1; + if (getModuleConfiguration(&m, &t, &n) == FAIL) { + return FAIL; + } + *retval = m; + return OK; +} + +int setTop(enum TOPINDEX t) { + char *top_names[] = {TOP_NAMES}; + LOG(logINFOBLUE, ("Setting up Top flag as %s\n", top_names[t])); +#ifdef VIRTUAL + switch (t) { + case OW_TOP: + top = 1; + break; + case OW_BOTTOM: + top = 0; + break; + default: + // hardware settings (do nothing) + break; + } +#else + if (!Beb_SetTop(t)) { + return FAIL; + } + + sharedMemory_lockLocalLink(); + if (!Feb_Control_SetTop(t, 1, 1)) { + sharedMemory_unlockLocalLink(); + return FAIL; + } + sharedMemory_unlockLocalLink(); + + // get and update top variable(cannot get from t, could be hardware) + if (isTop(&top) == FAIL) { + return FAIL; + } + // verify for master and slave (not hardware) + if ((t == OW_TOP && top == 0) || (t == OW_BOTTOM && top == 1)) { + LOG(logERROR, + ("could not set top/bottom. Top value retrieved %d\n", top)); + return FAIL; + } + + Beb_SetTopVariable(top); +#endif + return OK; +} + +int isTop(int *retval) { + int m = -1, t = -1, n = -1; + if (getModuleConfiguration(&m, &t, &n) == FAIL) { + return FAIL; + } + + *retval = t; + return OK; +} void setTiming(enum timingMode arg) { int ret = 0; diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index b3ebdf0cc..e964bd83d 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 0816cfa05..44c025b89 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -28,12 +28,16 @@ extern int updateFlag; extern int checkModuleFlag; extern udpStruct udpDetails[MAX_UDP_DESTINATION]; extern const enum detectorType myDetectorType; +extern int ignoreConfigFileFlag; // Global variable from communication_funcs.c extern int isControlServer; extern void getMacAddressinString(char *cmac, int size, uint64_t mac); extern void getIpAddressinString(char *cip, uint32_t ip); +// Variables that will be exported +int masterCommandLine = -1; + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -69,6 +73,7 @@ int64_t burstPeriodReg = 0; int filterResistor = 0; int cdsGain = 0; int detPos[2] = {}; +int master = 1; int isInitCheckDone() { return initCheckDone; } @@ -295,6 +300,18 @@ void setModuleId(int modid) { bus_r(MOD_ID_REG) | ((modid << MOD_ID_OFST) & MOD_ID_MSK)); } +int updateModuleId() { + int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE); + if (initError == FAIL) { + return FAIL; + } +#ifdef VIRTUAL + virtual_moduleid = modid; +#endif + setModuleId(modid); + return OK; +} + u_int64_t getDetectorMAC() { #ifdef VIRTUAL return 0; @@ -358,16 +375,27 @@ void initControlServer() { } void initStopServer() { - - usleep(CTRL_SRVR_INIT_TIME_US); - if (mapCSP0() == FAIL) { - LOG(logERROR, - ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); - exit(EXIT_FAILURE); - } + if (!updateFlag && initError == OK) { + usleep(CTRL_SRVR_INIT_TIME_US); + LOG(logINFOBLUE, ("Configuring Stop server\n")); + if (mapCSP0() == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, + "Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + return; + } #ifdef VIRTUAL - sharedMemory_setStop(0); + sharedMemory_setStop(0); + // not reading config file (nothing of interest to stop server) + if (checkCommandLineConfiguration() == FAIL) { + initCheckDone = 1; + return; + } #endif + } + initCheckDone = 1; } /* set up detector */ @@ -480,15 +508,13 @@ void setupDetector() { return; } - // set module id in register - int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE); -#ifdef VIRTUAL - virtual_moduleid = modid; -#endif - if (initError == FAIL) { + // master for virtual + if (checkCommandLineConfiguration() == FAIL) + return; + + if (updateModuleId() == FAIL) { return; } - setModuleId(modid); setBurstMode(DEFAULT_BURST_MODE); setFilterResistor(DEFAULT_FILTER_RESISTOR); @@ -600,6 +626,11 @@ int readConfigFile() { return initError; } + if (ignoreConfigFileFlag) { + LOG(logWARNING, ("Ignoring Config file\n")); + return OK; + } + // require a sleep before and after the rst dac signal usleep(INITIAL_STARTUP_WAIT); @@ -924,6 +955,21 @@ int readConfigFile() { return initError; } +int checkCommandLineConfiguration() { + if (masterCommandLine != -1) { +#ifdef VIRTUAL + master = masterCommandLine; +#else + initError = FAIL; + strcpy(initErrorMessage, + "Cannot set Master from command line for this detector. " + "Should have been caught before!\n"); + return FAIL; +#endif + } + return OK; +} + /* firmware functions (resets) */ void cleanFifos() { @@ -1451,6 +1497,11 @@ int setHighVoltage(int val) { /* parameters - timing */ +int isMaster(int *retval) { + *retval = master; + return OK; +} + void updatingRegisters() { LOG(logINFO, ("\tUpdating registers\n")); // burst @@ -1930,9 +1981,17 @@ int checkDetectorType() { return -2; } - if ((abs(type - TYPE_GOTTHARD2_MODULE_VAL) > TYPE_TOLERANCE) && - (abs(type - TYPE_GOTTHARD2_25UM_MASTER_MODULE_VAL) > TYPE_TOLERANCE) && - (abs(type - TYPE_GOTTHARD2_25UM_SLAVE_MODULE_VAL) > TYPE_TOLERANCE)) { + if (abs(type - TYPE_GOTTHARD2_25UM_MASTER_MODULE_VAL) <= TYPE_TOLERANCE) { + LOG(logINFOBLUE, ("MASTER 25um Module\n")); + master = 1; + } else if (abs(type - TYPE_GOTTHARD2_25UM_SLAVE_MODULE_VAL) <= + TYPE_TOLERANCE) { + master = 0; + LOG(logINFOBLUE, ("SLAVE 25um Module\n")); + } else if (abs(type - TYPE_GOTTHARD2_MODULE_VAL) <= TYPE_TOLERANCE) { + master = -1; + LOG(logINFOBLUE, ("50um Module\n")); + } else { LOG(logERROR, ("Wrong Module attached! Expected %d, %d or %d for Gotthard2, got " "%d\n", diff --git a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer index 3e8b3eecf..4891dd459 100755 Binary files a/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer and b/slsDetectorServers/gotthardDetectorServer/bin/gotthardDetectorServer_developer differ diff --git a/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c index ca415eeba..2060ff9f5 100644 --- a/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthardDetectorServer/slsDetectorFunctionList.c @@ -25,9 +25,11 @@ extern int debugflag; extern int updateFlag; extern udpStruct udpDetails[MAX_UDP_DESTINATION]; extern const enum detectorType myDetectorType; +extern int ignoreConfigFileFlag; // Variables that will be exported int phaseShift = DEFAULT_PHASE_SHIFT; +int masterCommandLine = -1; // Global variable from communication_funcs.c extern int isControlServer; @@ -359,16 +361,28 @@ void initControlServer() { } void initStopServer() { - if (mapCSP0() == FAIL) { - LOG(logERROR, - ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); - exit(EXIT_FAILURE); - } + if (!updateFlag && initError == OK) { + usleep(CTRL_SRVR_INIT_TIME_US); + LOG(logINFOBLUE, ("Configuring Stop server\n")); + if (mapCSP0() == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, + "Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + return; + } #ifdef VIRTUAL - sharedMemory_setStop(0); + sharedMemory_setStop(0); #endif - // to get master from file - readConfigFile(); + // to get master from file + if (readConfigFile() == FAIL || + checkCommandLineConfiguration() == FAIL) { + initCheckDone = 1; + return; + } + } + initCheckDone = 1; } /* set up detector */ @@ -421,6 +435,13 @@ void setupDetector() { setROI(rois); // set adcsyncreg, daqreg, chipofinterestreg, cleanfifos, setGbitReadout(); + // no config file or not first time server + if (readConfigFile() == FAIL) + return; + + if (checkCommandLineConfiguration() == FAIL) + return; + // master, slave (25um) setMasterSlaveConfiguration(); @@ -624,6 +645,16 @@ void setGbitReadout() { } int readConfigFile() { + + if (initError == FAIL) { + return initError; + } + + if (ignoreConfigFileFlag) { + LOG(logWARNING, ("Ignoring Config file\n")); + return OK; + } + const int fileNameSize = 128; char fname[fileNameSize]; if (getAbsPath(fname, fileNameSize, CONFIG_FILE) == FAIL) { @@ -647,7 +678,6 @@ int readConfigFile() { memset(key, 0, keySize); char value[keySize]; memset(value, 0, keySize); - int scan = OK; // keep reading a line while (fgets(line, lineSize, fd)) { @@ -667,19 +697,22 @@ int readConfigFile() { master = 0; LOG(logINFOBLUE, ("\tSlave or No Master\n")); } else { - LOG(logERROR, - ("\tCould not scan masterflags %s value from config file\n", - value)); - scan = FAIL; - break; + initError = FAIL; + sprintf( + initErrorMessage, + "Could not scan masterflags %s value from config file\n", + value); + LOG(logERROR, (initErrorMessage)) + fclose(fd); + return FAIL; } // not first server since detector power on if (!detectorFirstServer) { - LOG(logINFOBLUE, ("\tServer has been started up before. " - "Ignoring rest of config file\n")); + LOG(logWARNING, ("\tServer has been started up before. " + "Ignoring rest of config file\n")); fclose(fd); - return FAIL; + return OK; } } @@ -688,11 +721,14 @@ int readConfigFile() { // convert value to int int ival = 0; if (sscanf(value, "%d", &ival) <= 0) { - LOG(logERROR, ("\tCould not scan parameter %s value %s from " - "config file\n", - key, value)); - scan = FAIL; - break; + initError = FAIL; + sprintf(initErrorMessage, + "Could not scan parameter %s value %s from " + "config file\n", + key, value); + LOG(logERROR, (initErrorMessage)) + fclose(fd); + return FAIL; } // set value if (!strcasecmp(key, "masterdefaultdelay")) @@ -710,16 +746,16 @@ int readConfigFile() { else if (!strcasecmp(key, "startacqdelay")) startacqdelay = ival; else { - LOG(logERROR, - ("\tCould not scan parameter %s from config file\n", key)); - scan = FAIL; - break; + initError = FAIL; + sprintf(initErrorMessage, + "Could not scan parameter %s from config file\n", key); + LOG(logERROR, (initErrorMessage)) + fclose(fd); + return FAIL; } } } fclose(fd); - if (scan == FAIL) - exit(EXIT_FAILURE); LOG(logINFOBLUE, ("\tmasterdefaultdelay:%d\n" @@ -734,13 +770,28 @@ int readConfigFile() { return OK; } +int checkCommandLineConfiguration() { + if (masterCommandLine != -1) { +#ifdef VIRTUAL + master = masterCommandLine; +#else + initError = FAIL; + strcpy(initErrorMessage, + "Cannot set Master from command line for this detector. " + "Should have been caught before!\n"); + return FAIL; +#endif + } + return OK; +} + void setMasterSlaveConfiguration() { - LOG(logINFO, ("Reading Master Slave Configuration\n")); - - // no config file or not first time server - if (readConfigFile() == FAIL) + // not the first time its being read + if (!detectorFirstServer) { return; + } + LOG(logINFO, ("Reading Master Slave Configuration\n")); // master configuration if (master) { // master default delay set, so reset delay @@ -1247,7 +1298,10 @@ int setHighVoltage(int val) { /* parameters - timing, extsig */ -int isMaster() { return master; } +int isMaster(int *retval) { + *retval = master; + return OK; +} void setTiming(enum timingMode arg) { u_int32_t addr = EXT_SIGNAL_REG; diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index eec1da2d9..6a7f35571 100755 Binary files a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer and b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer differ diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 4a8bebcfd..46f8fa9a2 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -28,6 +28,7 @@ extern int updateFlag; extern udpStruct udpDetails[MAX_UDP_DESTINATION]; extern int numUdpDestinations; extern const enum detectorType myDetectorType; +extern int ignoreConfigFileFlag; // Global variable from communication_funcs.c extern int isControlServer; @@ -392,19 +393,29 @@ void initControlServer() { } void initStopServer() { - - usleep(CTRL_SRVR_INIT_TIME_US); - if (mapCSP0() == FAIL) { - LOG(logERROR, - ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); - exit(EXIT_FAILURE); - } + if (!updateFlag && initError == OK) { + usleep(CTRL_SRVR_INIT_TIME_US); + LOG(logINFOBLUE, ("Configuring Stop server\n")); + if (mapCSP0() == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, + "Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + return; + } + if (readConfigFile() == FAIL) { + initCheckDone = 1; + return; + } #ifdef VIRTUAL - sharedMemory_setStop(0); - // temp threshold and reset event (read by stop server) - setThresholdTemperature(DEFAULT_TMP_THRSHLD); - setTemperatureEvent(0); + sharedMemory_setStop(0); + // temp threshold and reset event (read by stop server) + setThresholdTemperature(DEFAULT_TMP_THRSHLD); + setTemperatureEvent(0); #endif + } + initCheckDone = 1; } /* set up detector */ @@ -643,6 +654,11 @@ int readConfigFile() { return initError; } + if (ignoreConfigFileFlag) { + LOG(logWARNING, ("Ignoring Config file\n")); + return OK; + } + const int fileNameSize = 128; char fname[fileNameSize]; if (getAbsPath(fname, fileNameSize, CONFIG_FILE) == FAIL) { diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index 8c99f07dc..2d11a95cb 100755 Binary files a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer and b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer differ diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 1bf765a99..99b2f2fe0 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -436,16 +436,22 @@ void initControlServer() { } void initStopServer() { - - usleep(CTRL_SRVR_INIT_TIME_US); - if (mapCSP0() == FAIL) { - LOG(logERROR, - ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); - exit(EXIT_FAILURE); - } + if (!updateFlag && initError == OK) { + usleep(CTRL_SRVR_INIT_TIME_US); + LOG(logINFOBLUE, ("Configuring Stop server\n")); + if (mapCSP0() == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, + "Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + return; + } #ifdef VIRTUAL - sharedMemory_setStop(0); + sharedMemory_setStop(0); #endif + } + initCheckDone = 1; } /* set up detector */ diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 046003d62..e716a5aa9 100755 Binary files a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer and b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer differ diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index 9179549fb..75b51de7b 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -35,6 +35,9 @@ extern int isControlServer; extern void getMacAddressinString(char *cmac, int size, uint64_t mac); extern void getIpAddressinString(char *cip, uint32_t ip); +// Variables that will be exported +int masterCommandLine = -1; + int initError = OK; int initCheckDone = 0; char initErrorMessage[MAX_STR_LENGTH]; @@ -289,6 +292,18 @@ void setModuleId(int modid) { bus_r(MOD_ID_REG) | ((modid << MOD_ID_OFST) & MOD_ID_MSK)); } +int updateModuleId() { + int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE); + if (initError == FAIL) { + return FAIL; + } +#ifdef VIRTUAL + virtual_moduleid = modid; +#endif + setModuleId(modid); + return OK; +} + u_int64_t getDetectorMAC() { #ifdef VIRTUAL return 0; @@ -352,16 +367,26 @@ void initControlServer() { } void initStopServer() { - - usleep(CTRL_SRVR_INIT_TIME_US); - if (mapCSP0() == FAIL) { - LOG(logERROR, - ("Stop Server: Map Fail. Dangerous to continue. Goodbye!\n")); - exit(EXIT_FAILURE); - } + if (!updateFlag && initError == OK) { + usleep(CTRL_SRVR_INIT_TIME_US); + LOG(logINFOBLUE, ("Configuring Stop server\n")); + if (mapCSP0() == FAIL) { + initError = FAIL; + strcpy(initErrorMessage, + "Stop Server: Map Fail. Dangerous to continue. Goodbye!\n"); + LOG(logERROR, (initErrorMessage)); + initCheckDone = 1; + return; + } #ifdef VIRTUAL - sharedMemory_setStop(0); + sharedMemory_setStop(0); + if (checkCommandLineConfiguration() == FAIL) { + initCheckDone = 1; + return; + } #endif + } + initCheckDone = 1; } /* set up detector */ @@ -407,6 +432,12 @@ void setupDetector() { allocateDetectorStructureMemory(); + if (checkCommandLineConfiguration() == FAIL) + return; + + if (updateModuleId() == FAIL) + return; + clkDivider[READOUT_C0] = DEFAULT_READOUT_C0; clkDivider[READOUT_C1] = DEFAULT_READOUT_C1; clkDivider[SYSTEM_C0] = DEFAULT_SYSTEM_C0; @@ -447,16 +478,6 @@ void setupDetector() { setASICDefaults(); setADIFDefaults(); - // set module id in register - int modid = getModuleIdInFile(&initError, initErrorMessage, ID_FILE); -#ifdef VIRTUAL - virtual_moduleid = modid; -#endif - if (initError == FAIL) { - return; - } - setModuleId(modid); - // set trigger flow for m3 (for all timing modes) bus_w(FLOW_TRIGGER_REG, bus_r(FLOW_TRIGGER_REG) | FLOW_TRIGGER_MSK); @@ -480,10 +501,6 @@ void setupDetector() { setInitialExtSignals(); // 10G UDP enableTenGigabitEthernet(1); - getModuleIdInFile(&initError, initErrorMessage, ID_FILE); - if (initError == FAIL) { - return; - } setSettings(DEFAULT_SETTINGS); // check module type attached if not in debug mode @@ -700,6 +717,27 @@ void setADIFDefaults() { ADIF_ADDTNL_OFST_MSK))); } +int checkCommandLineConfiguration() { + if (masterCommandLine != -1) { +#ifdef VIRTUAL + if (masterCommandLine == 1) { + bus_w(SYSTEM_STATUS_REG, + bus_r(SYSTEM_STATUS_REG) & ~SYSTEM_STATUS_SLV_BRD_DTCT_MSK); + } else { + bus_w(SYSTEM_STATUS_REG, + bus_r(SYSTEM_STATUS_REG) | SYSTEM_STATUS_SLV_BRD_DTCT_MSK); + } +#else + initError = FAIL; + strcpy(initErrorMessage, + "Cannot set Master from command line for this detector. " + "Should have been caught before!\n"); + return FAIL; +#endif + } + return OK; +} + /* firmware functions (resets) */ void cleanFifos() { @@ -1554,14 +1592,18 @@ int setHighVoltage(int val) { /* parameters - timing */ -int isMaster() { - return !((bus_r(SYSTEM_STATUS_REG) & SYSTEM_STATUS_SLV_BRD_DTCT_MSK) >> - SYSTEM_STATUS_SLV_BRD_DTCT_OFST); +int isMaster(int *retval) { + int slave = ((bus_r(SYSTEM_STATUS_REG) & SYSTEM_STATUS_SLV_BRD_DTCT_MSK) >> + SYSTEM_STATUS_SLV_BRD_DTCT_OFST); + *retval = (slave == 0 ? 1 : 0); + return OK; } void setTiming(enum timingMode arg) { - if (!isMaster() && arg == AUTO_TIMING) + int master = 0; + isMaster(&master); + if (master && arg == AUTO_TIMING) arg = TRIGGER_EXPOSURE; uint32_t addr = CONFIG_REG; diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index efc671d39..3bbf02e15 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -97,6 +97,9 @@ u_int32_t getDetectorNumber(); #if defined(GOTTHARD2D) || defined(EIGERD) || defined(MYTHEN3D) int getModuleId(int *ret, char *mess); #endif +#if defined(EIGERD) || defined(MYTHEN3D) || defined(GOTTHARD2D) +int updateModuleId(); +#endif #if defined(GOTTHARD2D) || defined(MYTHEN3D) void setModuleId(int modid); #endif @@ -110,7 +113,11 @@ u_int32_t getBoardRevision(); void initControlServer(); void initStopServer(); #ifdef EIGERD -void getModuleConfiguration(); +int updateModuleConfiguration(); +int getModuleConfiguration(int *m, int *t, int *n); +#ifdef VIRTUAL +void checkVirtual9MFlag(); +#endif #endif // set up detector @@ -137,6 +144,10 @@ void setADIFDefaults(); #if defined(GOTTHARD2D) || defined(EIGERD) || defined(JUNGFRAUD) int readConfigFile(); #endif +#if defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \ + defined(MYTHEN3D) +int checkCommandLineConfiguration(); +#endif #ifdef EIGERD void resetToHardwareSettings(); #endif @@ -363,9 +374,16 @@ int getADC(enum ADCINDEX ind); int setHighVoltage(int val); // parameters - timing, extsig -#if defined(MYTHEN3D) || defined(EIGERD) || defined(GOTTHARDD) -int isMaster(); +#ifdef EIGERD +int setMaster(enum MASTERINDEX m); +int setTop(enum TOPINDEX t); +int isTop(int *retval); #endif +#if defined(MYTHEN3D) || defined(EIGERD) || defined(GOTTHARDD) || \ + defined(GOTTHARD2D) +int isMaster(int *retval); +#endif + #ifdef GOTTHARD2D void updatingRegisters(); #endif diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index 8948e19d4..e68720305 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -245,6 +245,7 @@ int get_pattern(int); int load_default_pattern(int); int get_all_threshold_energy(int); int get_master(int); +int set_master(int); int get_csr(); int set_gain_caps(int); int get_gain_caps(int); @@ -289,4 +290,6 @@ void receive_program_default(int file_des, enum PROGRAM_INDEX index, char *functionType, uint64_t filesize, char *checksum, char *serverName); int get_update_mode(int); -int set_update_mode(int); \ No newline at end of file +int set_update_mode(int); +int get_top(int); +int set_top(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c index e11055123..2f9e3467b 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer.c @@ -26,11 +26,19 @@ extern int sockfd; extern int debugflag; extern int updateFlag; extern int checkModuleFlag; +extern int ignoreConfigFileFlag; // Global variables from slsDetectorFunctionList #ifdef GOTTHARDD extern int phaseShift; #endif +#if defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \ + defined(MYTHEN3D) +extern int masterCommandLine; +#endif +#ifdef EIGERD +extern int topCommandLine; +#endif void error(char *msg) { perror(msg); } @@ -48,6 +56,14 @@ int main(int argc, char *argv[]) { updateFlag = 0; checkModuleFlag = 1; int version = 0; + ignoreConfigFileFlag = 0; +#if defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \ + defined(MYTHEN3D) + masterCommandLine = -1; +#endif +#ifdef EIGERD + topCommandLine = -1; +#endif // help message char helpMessage[MAX_STR_LENGTH]; @@ -58,15 +74,23 @@ int main(int argc, char *argv[]) { "Possible arguments are:\n" "\t-v, --version : Software version\n" "\t-p, --port : TCP communication port with client. \n" - "\t-g, --nomodule : [Mythen3][Gotthard2] Generic or No " - "Module mode. Skips detector type checks. \n" + "\t-g, --nomodule : [Mythen3][Gotthard2] \n" + "\t Generic or No Module mode. Skips " + "detector type checks. \n" "\t-f, --phaseshift : [Gotthard] only. Sets phase shift. \n" "\t-d, --devel : Developer mode. Skips firmware checks. \n" "\t-u, --update : Update mode. Skips firmware checks and " "initial detector setup. \n" + "\t-i, --ignore-config : " + "[Eiger][Jungfrau][Gotthard][Gotthard2] \n" + "\t Ignore config file. \n" + "\t-m, --master : [Eiger][Mythen3][Gotthard][Gotthard2] \n" + "\t Set Master to 0 or 1. Precedence over " + "config file. Only for virtual servers except Eiger. \n" + "\t-t, --top : [Eiger] Set Top to 0 or 1. Precedence " + "over config file. \n" "\t-s, --stopserver : Stop server. Do not use as it is created " - "by " - "control server \n\n", + "by control server \n\n", argv[0]); // parse command line for config @@ -80,6 +104,9 @@ int main(int argc, char *argv[]) { {"nomodule", no_argument, NULL, 'g'}, // generic {"devel", no_argument, NULL, 'd'}, {"update", no_argument, NULL, 'u'}, + {"ignore-config", no_argument, NULL, 'i'}, + {"master", required_argument, NULL, 'm'}, + {"top", required_argument, NULL, 't'}, {"stopserver", no_argument, NULL, 's'}, {NULL, 0, NULL, 0}}; @@ -89,7 +116,8 @@ int main(int argc, char *argv[]) { int c = 0; while (c != -1) { - c = getopt_long(argc, argv, "hvp:f:gdus", long_options, &option_index); + c = getopt_long(argc, argv, "hvp:f:gduim:t:s", long_options, + &option_index); // Detect the end of the options if (c == -1) @@ -160,6 +188,57 @@ int main(int argc, char *argv[]) { isControlServer = 0; break; + case 'i': +#if defined(EIGERD) || defined(GOTTHARDD) || defined(GOTTHARD2D) || \ + defined(JUNGFRAUD) + LOG(logINFO, ("Ignoring config file\n")); + ignoreConfigFileFlag = 1; +#else + LOG(logERROR, ("No server config files for this detector\n")); + exit(EXIT_FAILURE); +#endif + break; + + case 'm': +#if (defined(MYTHEN3D) || defined(GOTTHARDD) || defined(GOTTHARD2D)) && \ + !defined(VIRTUAL) + LOG(logERROR, ("Cannot set master via the detector server for this " + "detector\n")); + exit(EXIT_FAILURE); +#elif defined(GOTTHARDD) || defined(GOTTHARD2D) || defined(EIGERD) || \ + defined(MYTHEN3D) + if (sscanf(optarg, "%d", &masterCommandLine) != 1) { + LOG(logERROR, ("Cannot scan master argument\n%s", helpMessage)); + exit(EXIT_FAILURE); + } + if (masterCommandLine == 1) { + LOG(logINFO, ("Detector Master mode\n")); + } else { + LOG(logINFO, ("Detector Slave mode\n")); + } +#else + LOG(logERROR, ("No master implemented for this detector server\n")); + exit(EXIT_FAILURE); +#endif + break; + + case 't': +#ifdef EIGERD + if (sscanf(optarg, "%d", &topCommandLine) != 1) { + LOG(logERROR, ("Cannot scan top argument\n%s", helpMessage)); + exit(EXIT_FAILURE); + } + if (topCommandLine == 1) { + LOG(logINFO, ("Detector Top mode\n")); + } else { + LOG(logINFO, ("Detector Bottom mode\n")); + } +#else + LOG(logERROR, ("No top implemented for this detector server\n")); + exit(EXIT_FAILURE); +#endif + break; + case 'h': printf("%s", helpMessage); exit(EXIT_SUCCESS); diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 956591314..796dd4f3f 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -54,6 +54,7 @@ int sockfd = 0; int debugflag = 0; int updateFlag = 0; int checkModuleFlag = 1; +int ignoreConfigFileFlag = 0; udpStruct udpDetails[MAX_UDP_DESTINATION]; int numUdpDestinations = 1; @@ -468,6 +469,9 @@ void function_table() { flist[F_UPDATE_DETECTOR_SERVER] = &update_detector_server; flist[F_GET_UPDATE_MODE] = &get_update_mode; flist[F_SET_UPDATE_MODE] = &set_update_mode; + flist[F_SET_MASTER] = &set_master; + flist[F_GET_TOP] = &get_top; + flist[F_SET_TOP] = &set_top; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -3991,29 +3995,26 @@ int check_version(int file_des) { return printSocketReadError(); // check software- firmware compatibility and basic tests - if (isControlServer) { - LOG(logDEBUG1, ("Checking software-firmware compatibility and basic " - "test result\n")); + LOG(logDEBUG1, ("Checking software-firmware compatibility and basic " + "test result\n")); - // check if firmware check is done + // check if firmware check is done + if (!isInitCheckDone()) { + usleep(3 * 1000 * 1000); if (!isInitCheckDone()) { - usleep(3 * 1000 * 1000); - if (!isInitCheckDone()) { - ret = FAIL; - strcpy(mess, "Firmware Software Compatibility Check (Server " - "Initialization) " - "still not done done in server. Unexpected.\n"); - LOG(logERROR, (mess)); - } + ret = FAIL; + strcpy(mess, "Server Initialization still not done done in server. Unexpected.\n"); + LOG(logERROR, (mess)); } - // check firmware check result - if (ret == OK) { - char *firmware_message = NULL; - if (getInitResult(&firmware_message) == FAIL) { - ret = FAIL; - strcpy(mess, firmware_message); - LOG(logERROR, (mess)); - } + } + + // check firmware check result + if (ret == OK) { + char *firmware_message = NULL; + if (getInitResult(&firmware_message) == FAIL) { + ret = FAIL; + strcpy(mess, firmware_message); + LOG(logERROR, (mess)); } } @@ -8217,14 +8218,60 @@ int get_master(int file_des) { LOG(logDEBUG1, ("Getting master\n")); -#if !defined(MYTHEN3D) && !defined(EIGERD) && !defined(GOTTHARDD) +#if !defined(MYTHEN3D) && !defined(EIGERD) && !defined(GOTTHARDD) && \ + !defined(GOTTHARD2D) functionNotImplemented(); #else - retval = isMaster(); + ret = isMaster(&retval); + if (ret == FAIL) { + strcpy(mess, "Could not get master\n"); + LOG(logERROR, (mess)); + } #endif return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } +int set_master(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + LOG(logDEBUG1, ("Setting master: %u\n", (int)arg)); + +#ifndef EIGERD + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + if ((check_detector_idle("set master") == OK) && + (arg != 0 && arg != 1)) { + ret = FAIL; + sprintf(mess, "Could not set master. Invalid argument %d.\n", arg); + LOG(logERROR, (mess)); + } else { + ret = setMaster(arg == 1 ? OW_MASTER : OW_SLAVE); + if (ret == FAIL) { + strcpy(mess, "Could not set master\n"); + LOG(logERROR, (mess)); + } else { + int retval = 0; + ret = isMaster(&retval); + if (ret == FAIL) { + strcpy(mess, "Could not get master\n"); + LOG(logERROR, (mess)); + } else { + LOG(logDEBUG1, ("master retval: %u\n", retval)); + validate(&ret, mess, arg, retval, "set master", DEC); + } + } + } + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} + int get_csr(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -9697,5 +9744,67 @@ int set_update_mode(int file_des) { } } + return Server_SendResult(file_des, INT32, NULL, 0); +} + +int get_top(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; + LOG(logDEBUG1, ("Getting top\n")); + +#ifndef EIGERD + functionNotImplemented(); +#else + // get only + ret = isTop(&retval); + if (ret == FAIL) { + strcpy(mess, "Could not get Top\n"); + LOG(logERROR, (mess)); + } else { + LOG(logDEBUG1, ("retval top: %d\n", retval)); + } +#endif + return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); +} + +int set_top(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + LOG(logDEBUG1, ("Setting top : %u\n", arg)); + +#ifndef EIGERD + functionNotImplemented(); +#else + + // only set + if (Server_VerifyLock() == OK) { + if (arg != 0 && arg != 1) { + ret = FAIL; + sprintf(mess, "Could not set top mode. Invalid value: %d. Must be 0 or 1\n", arg); + LOG(logERROR, (mess)); + } else { + ret = setTop(arg == 1 ? OW_TOP : OW_BOTTOM); + if (ret == FAIL) { + sprintf(mess, "Could not set %s\n", (arg == 1 ? "Top" : "Bottom")); + LOG(logERROR, (mess)); + } else { + int retval = -1; + ret = isTop(&retval); + if (ret == FAIL) { + strcpy(mess, "Could not get Top mode\n"); + LOG(logERROR, (mess)); + } else { + LOG(logDEBUG1, ("retval top: %d\n", retval)); + validate(&ret, mess, arg, retval, "set top mode", DEC); + } + } + } + } +#endif return Server_SendResult(file_des, INT32, NULL, 0); } \ No newline at end of file diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index c7e091dbc..b0bf69d71 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -193,6 +193,12 @@ class Detector { */ void setFlipRows(bool value, Positions pos = {}); + /** [Eiger][Mythen3][Gotthard1] via stop server **/ + Result getMaster(Positions pos = {}) const; + + /** [Eiger] Set half module to master and the others to slaves */ + void setMaster(bool value, int pos); + Result isVirtualDetectorServer(Positions pos = {}) const; ///@} @@ -1151,6 +1157,12 @@ class Detector { void setDataStream(const defs::portPosition port, const bool enable, Positions pos = {}); + /** [Eiger] Advanced */ + Result getTop(Positions pos = {}) const; + + /** [Eiger] Advanced. Default is hardware default */ + void setTop(bool value, Positions pos = {}); + ///@} /** @name Jungfrau Specific */ @@ -1448,9 +1460,6 @@ class Detector { * (internal gating). Gate index: 0-2, -1 for all */ Result> getGateDelayForAllGates(Positions pos = {}) const; - /** [Eiger][Mythen3][Gotthard1] via stop server **/ - Result getMaster(Positions pos = {}) const; - // TODO! check if we really want to expose this !!!!! Result getChipStatusRegister(Positions pos = {}) const; diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 95155b1b2..1de4fc47b 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -784,6 +784,7 @@ class CmdProxy { {"trimen", &CmdProxy::TrimEnergies}, {"gappixels", &CmdProxy::GapPixels}, {"fliprows", &CmdProxy::fliprows}, + {"master", &CmdProxy::master}, /* acquisition parameters */ {"acquire", &CmdProxy::Acquire}, @@ -942,6 +943,7 @@ class CmdProxy { {"pulsechip", &CmdProxy::PulseChip}, {"quad", &CmdProxy::Quad}, {"datastream", &CmdProxy::DataStream}, + {"top", &CmdProxy::top}, /* Jungfrau Specific */ {"chipversion", &CmdProxy::chipversion}, @@ -1280,6 +1282,12 @@ class CmdProxy { "interfaces must be set to 2. slsReceiver and slsDetectorGui " "does not handle."); + INTEGER_COMMAND_VEC_ID_GET( + master, getMaster, setMaster, StringTo, + "[0, 1]\n\t[Eiger] Sets half module to master and " + "others to slaves.\n\t[Gotthard][Gotthard2][Mythen3][Eiger] " + "Gets if the current module/ half module is master."); + /* acquisition parameters */ INTEGER_COMMAND_SET_NOID_GET_ID( @@ -1900,6 +1908,10 @@ class CmdProxy { "start of acquisition. 0 complete reset, 1 partial reset. Default is " "complete reset. Advanced function!"); + INTEGER_COMMAND_VEC_ID( + top, getTop, setTop, StringTo, + "[0, 1]\n\t[Eiger] Sets half module to top (1), else bottom."); + /* Jungfrau Specific */ GET_COMMAND(chipversion, getChipVersion, diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 74337c281..0c4fac5bf 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -298,6 +298,23 @@ void Detector::setFlipRows(bool value, Positions pos) { pimpl->Parallel(&Module::setFlipRows, pos, value); } +Result Detector::getMaster(Positions pos) const { + return pimpl->Parallel(&Module::isMaster, pos); +} + +void Detector::setMaster(bool master, int pos) { + // multi mod, set slaves first + if (master && size() > 1) { + if (pos == -1) { + throw RuntimeError("Master can be set only to a single module"); + } + pimpl->Parallel(&Module::setMaster, {}, false); + pimpl->Parallel(&Module::setMaster, {pos}, master); + } else { + pimpl->Parallel(&Module::setMaster, {pos}, master); + } +} + Result Detector::isVirtualDetectorServer(Positions pos) const { return pimpl->Parallel(&Module::isVirtualDetectorServer, pos); } @@ -1488,6 +1505,14 @@ void Detector::setDataStream(const defs::portPosition port, const bool enable, pimpl->Parallel(&Module::setDataStream, pos, port, enable); } +Result Detector::getTop(Positions pos) const { + return pimpl->Parallel(&Module::getTop, pos); +} + +void Detector::setTop(bool value, Positions pos) { + pimpl->Parallel(&Module::setTop, pos, value); +} + // Jungfrau Specific Result Detector::getChipVersion(Positions pos) const { return pimpl->Parallel(&Module::getChipVersion, pos); @@ -1808,10 +1833,6 @@ Detector::getGateDelayForAllGates(Positions pos) const { return pimpl->Parallel(&Module::getGateDelayForAllGates, pos); } -Result Detector::getMaster(Positions pos) const { - return pimpl->Parallel(&Module::isMaster, pos); -} - Result Detector::getChipStatusRegister(Positions pos) const { return pimpl->Parallel(&Module::getChipStatusRegister, pos); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 599a754b8..1fcfdb3fb 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -509,6 +509,13 @@ void Module::setFlipRows(bool value) { } } +bool Module::isMaster() const { return sendToDetectorStop(F_GET_MASTER); } + +void Module::setMaster(const bool master) { + sendToDetector(F_SET_MASTER, static_cast(master), nullptr); + sendToDetectorStop(F_SET_MASTER, static_cast(master), nullptr); +} + bool Module::isVirtualDetectorServer() const { return sendToDetector(F_IS_VIRTUAL); } @@ -1673,6 +1680,14 @@ void Module::setDataStream(const portPosition port, const bool enable) { } } +bool Module::getTop() const { + return (static_cast(sendToDetector(F_GET_TOP))); +} + +void Module::setTop(bool value) { + sendToDetector(F_SET_TOP, static_cast(value), nullptr); +} + // Jungfrau Specific double Module::getChipVersion() const { return (sendToDetector(F_GET_CHIP_VERSION)) / 10.00; @@ -2197,8 +2212,6 @@ std::array Module::getGateDelayForAllGates() const { return sendToDetector>(F_GET_GATE_DELAY_ALL_GATES); } -bool Module::isMaster() const { return sendToDetectorStop(F_GET_MASTER); } - int Module::getChipStatusRegister() const { return sendToDetector(F_GET_CSR); } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 217b35075..375911ceb 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -120,6 +120,9 @@ class Module : public virtual slsDetectorDefs { int setTrimEn(const std::vector &energies = {}); bool getFlipRows() const; void setFlipRows(bool value); + bool isMaster() const; + void setMaster(const bool master); + bool isVirtualDetectorServer() const; /************************************************** @@ -184,6 +187,7 @@ class Module : public virtual slsDetectorDefs { void setDBITPipeline(int value); int getReadNRows() const; void setReadNRows(const int value); + /************************************************** * * * Acquisition * @@ -365,6 +369,8 @@ class Module : public virtual slsDetectorDefs { void setQuad(const bool enable); bool getDataStream(const portPosition port) const; void setDataStream(const portPosition port, const bool enable); + bool getTop() const; + void setTop(bool value); /************************************************** * * @@ -456,7 +462,6 @@ class Module : public virtual slsDetectorDefs { int64_t getGateDelay(int gateIndex) const; void setGateDelay(int gateIndex, int64_t value); std::array getGateDelayForAllGates() const; - bool isMaster() const; int getChipStatusRegister() const; void setGainCaps(int caps); int getGainCaps(); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp index 27b4b7129..6536275cf 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp @@ -629,4 +629,32 @@ TEST_CASE("datastream", "[.cmd]") { REQUIRE_THROWS(proxy.Call("datastream", {"1"}, -1, PUT)); REQUIRE_THROWS(proxy.Call("datastream", {"left", "1"}, -1, PUT)); } +} + +TEST_CASE("top", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + auto prev_val = det.getTop(); + int numModulesTested = 1; + if (det.size() > 1) { + numModulesTested = 2; + } + for (int i = 0; i != numModulesTested; ++i) { + std::ostringstream oss1, oss2, oss3; + proxy.Call("top", {"1"}, i, PUT, oss1); + REQUIRE(oss1.str() == "top 1\n"); + proxy.Call("top", {}, i, GET, oss2); + REQUIRE(oss2.str() == "top 1\n"); + proxy.Call("top", {"0"}, i, PUT, oss3); + REQUIRE(oss3.str() == "top 0\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setTop(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("top", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("top", {"1"}, -1, PUT)); + } } \ No newline at end of file diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index 4a593eb95..4b8320dec 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -570,6 +570,46 @@ TEST_CASE("fliprows", "[.cmd]") { } } +TEST_CASE("master", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER || det_type == defs::MYTHEN3 || det_type == defs::GOTTHARD || det_type == defs::GOTTHARD2) { + REQUIRE_NOTHROW(proxy.Call("master", {}, -1, GET)); + if (det_type == defs::EIGER) { + // get previous master + int prevMaster = 0; + { + auto previous = det.getMaster(); + for (int i = 0; i != det.size(); ++i) { + if (previous[i] == 1) { + prevMaster = i; + break; + } + } + } + { + std::ostringstream oss1; + proxy.Call("master", {"0"}, 0, PUT, oss3); + REQUIRE(oss3.str() == "master 0\n"); + } + { + std::ostringstream oss1; + proxy.Call("master", {"1"}, 0, PUT, oss3); + REQUIRE(oss3.str() == "master 1\n"); + } + REQUIRE_THROWS(proxy.Call("master", {"1"}, -1, PUT)); + // set all to slaves, and then master + for (int i = 0; i != det.size(); ++i) { + det.setMaster(0, {i}); + } + det.setMaster(1, prevMaster); + } + } else { + REQUIRE_THROWS(proxy.Call("master", {}, -1, GET)); + } +} + /* acquisition parameters */ // acquire: not testing diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index ca7a19de2..13db10087 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -258,6 +258,9 @@ enum detFuncs { F_UPDATE_DETECTOR_SERVER, F_GET_UPDATE_MODE, F_SET_UPDATE_MODE, + F_SET_MASTER, + F_GET_TOP, + F_SET_TOP, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -619,6 +622,9 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_UPDATE_DETECTOR_SERVER: return "F_UPDATE_DETECTOR_SERVER"; case F_GET_UPDATE_MODE: return "F_GET_UPDATE_MODE"; case F_SET_UPDATE_MODE: return "F_SET_UPDATE_MODE"; + case F_SET_MASTER: return "F_SET_MASTER"; + case F_GET_TOP: return "F_GET_TOP"; + case F_SET_TOP: return "F_SET_TOP"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 02cba7f71..cd0de911f 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -6,10 +6,10 @@ #define APIRECEIVER 0x211124 #define APIGUI 0x211124 -#define APICTB 0x220223 -#define APIGOTTHARD 0x220223 -#define APIGOTTHARD2 0x220223 -#define APIJUNGFRAU 0x220223 -#define APIMYTHEN3 0x220223 -#define APIMOENCH 0x220223 -#define APIEIGER 0x220223 +#define APICTB 0x220317 +#define APIGOTTHARD 0x220317 +#define APIGOTTHARD2 0x220317 +#define APIJUNGFRAU 0x220317 +#define APIMYTHEN3 0x220317 +#define APIMOENCH 0x220317 +#define APIEIGER 0x220317