diff --git a/RELEASE.txt b/RELEASE.txt index ecf3fd3b2..b9c0b1c0a 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) @@ -39,7 +39,12 @@ This document describes the differences between v7.0.0 and v6.x.x - current frame index points to listened frame index (not processed index) - when in discard partial frames or empty mode, the frame number doesnt increase by 1, it increases to that number (so its faster) - 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) - added geometry to metadata 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 1d2ec6218..e8aff9479 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -287,7 +287,7 @@ class Detector(CppDetectorApi): Note ----- - [Eiger] Options: 4, 8, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n + [Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets clkdivider to 2 (quarter speed), else to 0 (full speed)\n [Mythen3] Options: 8, 16, 32 \n [Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16 """ @@ -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/slsDetectorGui/forms/form_tab_settings.ui b/slsDetectorGui/forms/form_tab_settings.ui index 32890e2d0..d99e9d9ba 100755 --- a/slsDetectorGui/forms/form_tab_settings.ui +++ b/slsDetectorGui/forms/form_tab_settings.ui @@ -97,6 +97,11 @@ 65535 + + + 4095 + + 255 diff --git a/slsDetectorGui/include/qTabSettings.h b/slsDetectorGui/include/qTabSettings.h index 2a2a2c8af..a2a6ad73e 100644 --- a/slsDetectorGui/include/qTabSettings.h +++ b/slsDetectorGui/include/qTabSettings.h @@ -69,5 +69,11 @@ class qTabSettings : public QWidget, private Ui::TabSettingsObject { enum { DYNAMIC, FORCE_SWITCH_G1, FORCE_SWITCH_G2, FIX_G1, FIX_G2, FIX_G0 }; bool isVisibleFixG0{false}; - enum { DYNAMICRANGE_32, DYNAMICRANGE_16, DYNAMICRANGE_8, DYNAMICRANGE_4 }; + enum { + DYNAMICRANGE_32, + DYNAMICRANGE_16, + DYNAMICRANGE_12, + DYNAMICRANGE_8, + DYNAMICRANGE_4 + }; }; diff --git a/slsDetectorGui/src/qDrawPlot.cpp b/slsDetectorGui/src/qDrawPlot.cpp index 40edc1538..a95c9efcd 100644 --- a/slsDetectorGui/src/qDrawPlot.cpp +++ b/slsDetectorGui/src/qDrawPlot.cpp @@ -1064,6 +1064,8 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size, // mythen3 / gotthard2 debugging int discardBits = numDiscardBits; + uint16_t temp = 0; + uint8_t *src = (uint8_t *)source; switch (dr) { case 4: @@ -1083,6 +1085,19 @@ void qDrawPlot::toDoublePixelData(double *dest, char *source, int size, } break; + case 12: + for (ichan = 0; ichan < size; ++ichan) { + temp = (*src++ & 0xFF); + temp |= ((*src & 0xF) << 8u); + dest[ichan] = (double)temp; + ++ichan; + + temp = ((*src++ & 0xF0) >> 4u); + temp |= ((*src++ & 0xFF) << 4u); + dest[ichan] = (double)temp; + } + break; + case 16: if (detType == slsDetectorDefs::JUNGFRAU || detType == slsDetectorDefs::GOTTHARD2) { diff --git a/slsDetectorGui/src/qTabSettings.cpp b/slsDetectorGui/src/qTabSettings.cpp index dcee0a450..9a3d97132 100644 --- a/slsDetectorGui/src/qTabSettings.cpp +++ b/slsDetectorGui/src/qTabSettings.cpp @@ -60,13 +60,19 @@ void qTabSettings::SetupWidgetWindow() { QStandardItemModel *model = qobject_cast(comboDynamicRange->model()); if (model) { - QModelIndex index; QStandardItem *item; - index = - model->index(DYNAMICRANGE_4, comboDynamicRange->modelColumn(), - comboDynamicRange->rootModelIndex()); - item = model->itemFromIndex(index); - item->setEnabled(false); + int dr = DYNAMICRANGE_4; + for (int i = 0; i != 2; ++i) { + // disable dr 4 + QModelIndex index = + model->index(dr, comboDynamicRange->modelColumn(), + comboDynamicRange->rootModelIndex()); + item = model->itemFromIndex(index); + item->setEnabled(false); + + // disable dr 12 + dr = DYNAMICRANGE_12; + } } } else if (detType == slsDetectorDefs::EIGER) { lblDynamicRange->setEnabled(true); @@ -305,6 +311,9 @@ void qTabSettings::GetDynamicRange() { case 16: comboDynamicRange->setCurrentIndex(DYNAMICRANGE_16); break; + case 12: + comboDynamicRange->setCurrentIndex(DYNAMICRANGE_12); + break; case 8: comboDynamicRange->setCurrentIndex(DYNAMICRANGE_8); break; @@ -333,6 +342,9 @@ void qTabSettings::SetDynamicRange(int index) { case DYNAMICRANGE_16: det->setDynamicRange(16); break; + case DYNAMICRANGE_12: + det->setDynamicRange(12); + break; case DYNAMICRANGE_8: det->setDynamicRange(8); break; diff --git a/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer b/slsDetectorServers/ctbDetectorServer/bin/ctbDetectorServer_developer index 044bb0569..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 06999e54d..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 */ @@ -702,8 +707,16 @@ void resetPeripheral() { } /* set parameters - dr, adcenablemask */ +int setDynamicRange(int dr) { + if (dr == 16) + return OK; + return FAIL; +} -int setDynamicRange(int dr) { return DYNAMIC_RANGE; } +int getDynamicRange(int *retval) { + *retval = DYNAMIC_RANGE; + return OK; +} int setADCEnableMask(uint32_t mask) { if (mask == 0u) { diff --git a/slsDetectorServers/eigerDetectorServer/Beb.c b/slsDetectorServers/eigerDetectorServer/Beb.c index 90512c7b1..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) { @@ -862,11 +864,17 @@ void Beb_ResetFrameNumber() { } int Beb_SetUpTransferParameters(short the_bit_mode) { - if (the_bit_mode != 4 && the_bit_mode != 8 && the_bit_mode != 16 && - the_bit_mode != 32) + switch (the_bit_mode) { + case 4: + case 8: + case 12: + case 16: + case 32: + Beb_bit_mode = the_bit_mode; + return 1; + default: return 0; - Beb_bit_mode = the_bit_mode; - return 1; + } } int Beb_StopAcquisition() { 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 27d98a30a..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) { @@ -931,7 +930,10 @@ unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec) { int Feb_Control_PrepareForAcquisition() { LOG(logINFOBLUE, ("Preparing for Acquisition\n")); - Feb_Control_PrintAcquisitionSetup(); + if (!Feb_Control_PrintAcquisitionSetup()) { + LOG(logERROR, ("Could not prepare acquisition\n")); + return 0; + } if (Feb_Control_Reset() == STATUS_ERROR) { LOG(logERROR, ("Trouble reseting daq or data stream\n")); @@ -988,20 +990,26 @@ int Feb_Control_PrepareForAcquisition() { return 1; } -void Feb_Control_PrintAcquisitionSetup() { +int Feb_Control_PrintAcquisitionSetup() { time_t rawtime; time(&rawtime); struct tm *timeinfo = localtime(&rawtime); - LOG(logINFO, - ("Starting an exposure: (%s)" - "\t Dynamic range nbits: %d\n" - "\t Trigger mode: 0x%x\n" - "\t Number of exposures: %d\n" - "\t Exsposure time (if used): %f seconds.\n" - "\t Exsposure period (if used): %f seconds.\n\n", - asctime(timeinfo), Feb_Control_GetDynamicRange(), - Feb_Control_triggerMode, Feb_Control_GetNExposures(), - Feb_Control_exposure_time_in_sec, Feb_Control_exposure_period_in_sec)); + int dr = 0; + if (!Feb_Control_GetDynamicRange(&dr)) { + LOG(logERROR, ("Could not print acquisition set up\n")); + return 0; + } + LOG(logINFO, ("Starting an exposure: (%s)" + "\t Dynamic range nbits: %d\n" + "\t Trigger mode: 0x%x\n" + "\t Number of exposures: %d\n" + "\t Exsposure time (if used): %f seconds.\n" + "\t Exsposure period (if used): %f seconds.\n\n", + asctime(timeinfo), dr, Feb_Control_triggerMode, + Feb_Control_GetNExposures(), Feb_Control_exposure_time_in_sec, + Feb_Control_exposure_period_in_sec)); + + return 1; } int Feb_Control_StartAcquisition() { @@ -1169,49 +1177,106 @@ int Feb_Control_SoftwareTrigger(int block) { } // parameters -int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo) { +int Feb_Control_SetDynamicRange(int dr) { static unsigned int everything_but_bit_mode = DAQ_STATIC_BIT_PROGRAM | DAQ_STATIC_BIT_CHIP_TEST | DAQ_STATIC_BIT_ROTEST; - if (four_eight_sixteen_or_thirtytwo == 4) { + switch (dr) { + case 4: Feb_Control_staticBits = DAQ_STATIC_BIT_M4 | (Feb_Control_staticBits & everything_but_bit_mode); // leave test bits in currernt state Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; - } else if (four_eight_sixteen_or_thirtytwo == 8) { + break; + case 8: Feb_Control_staticBits = DAQ_STATIC_BIT_M8 | (Feb_Control_staticBits & everything_but_bit_mode); Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; - } else if (four_eight_sixteen_or_thirtytwo == 16) { + break; + case 12: + case 16: Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits & everything_but_bit_mode); Feb_Control_subFrameMode &= ~DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; - } else if (four_eight_sixteen_or_thirtytwo == 32) { + + // disable 16 bit conversion if 12 bit mode (enable if 16 bit) + if (!Feb_Control_Disable16bitConversion(dr == 12)) + return 0; + break; + case 32: Feb_Control_staticBits = DAQ_STATIC_BIT_M12 | (Feb_Control_staticBits & everything_but_bit_mode); Feb_Control_subFrameMode |= DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING; - } else { - LOG(logERROR, ("dynamic range (%d) not valid, not setting bit mode.\n", - four_eight_sixteen_or_thirtytwo)); + break; + default: + LOG(logERROR, + ("dynamic range (%d) not valid, not setting bit mode.\n", dr)); LOG(logINFO, ("Set dynamic range int must equal 4,8 16, or 32.\n")); return 0; } - LOG(logINFO, - ("Dynamic range set to %d\n", four_eight_sixteen_or_thirtytwo)); + LOG(logINFO, ("Dynamic range set to %d\n", dr)); return 1; } -unsigned int Feb_Control_GetDynamicRange() { - if (Feb_Control_subFrameMode & DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) - return 32; - else if (DAQ_STATIC_BIT_M4 & Feb_Control_staticBits) - return 4; - else if (DAQ_STATIC_BIT_M8 & Feb_Control_staticBits) - return 8; +int Feb_Control_GetDynamicRange(int *retval) { + if (Feb_Control_subFrameMode & DAQ_NEXPOSURERS_ACTIVATE_AUTO_SUBIMAGING) { + *retval = 32; + } else if (DAQ_STATIC_BIT_M4 & Feb_Control_staticBits) { + *retval = 4; + } else if (DAQ_STATIC_BIT_M8 & Feb_Control_staticBits) { + *retval = 8; + } else { + int disable16 = 0; + if (!Feb_Control_Get16bitConversionDisabled(&disable16)) { + LOG(logERROR, ("Could not get dynamic range (12 or 16 bit)\n")); + return 0; + } + if (disable16) { + *retval = 12; + } else { + *retval = 16; + } + } - return 16; + return 1; +} + +int Feb_Control_Disable16bitConversion(int disable) { + LOG(logINFO, ("%s 16 bit expansion\n", disable ? "Disabling" : "Enabling")); + unsigned int regval = 0; + if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, ®val)) { + LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n", + (disable ? "disable" : "enable"))); + return 0; + } + if (disable) { + regval |= DAQ_REG_HRDWRE_DSBL_16BIT_MSK; + } else { + regval &= ~DAQ_REG_HRDWRE_DSBL_16BIT_MSK; + } + + if (!Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval)) { + LOG(logERROR, ("Could not %s 16 bit expansion (bit mode)\n", + (disable ? "disable" : "enable"))); + return 0; + } + return 1; +} + +int Feb_Control_Get16bitConversionDisabled(int *ret) { + unsigned int regval = 0; + if (!Feb_Control_ReadRegister(DAQ_REG_HRDWRE, ®val)) { + LOG(logERROR, ("Could not get 16 bit expansion (bit mode)\n")); + return 0; + } + if (regval & DAQ_REG_HRDWRE_DSBL_16BIT_MSK) { + *ret = 1; + } else { + *ret = 0; + } + return 1; } int Feb_Control_SetReadoutSpeed(unsigned int readout_speed) { @@ -1490,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}; @@ -1529,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; @@ -1554,7 +1640,10 @@ int Feb_Control_SetChipSignalsToTrimQuad(int enable) { regval &= ~(DAQ_REG_HRDWRE_PROGRAM_MSK | DAQ_REG_HRDWRE_M8_MSK); } - return Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval); + if (!Feb_Control_WriteRegister(DAQ_REG_HRDWRE, regval)) { + LOG(logERROR, ("Could not set chip signals to trim quad\n")); + return 0; + } } return 1; } @@ -1604,7 +1693,7 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { for (int iloop = 0; iloop < 2; ++iloop) { if (run[iloop]) { - LOG(logINFO, + LOG(logDEBUG1, ("Writing 0x%x to %s 0x%x\n", data, side[iloop], actualOffset)); if (!Feb_Interface_WriteRegister(addr[iloop], actualOffset, data, 0, 0)) { @@ -1612,6 +1701,18 @@ int Feb_Control_WriteRegister(uint32_t offset, uint32_t data) { side[iloop], actualOffset)); return 0; } + uint32_t regVal = 0; + if (!Feb_Interface_ReadRegister(addr[iloop], actualOffset, + ®Val)) { + LOG(logERROR, ("Could not read %s register\n", addr[iloop])); + return 0; + } + if (regVal != data) { + LOG(logERROR, + ("Could not write %s register. Write 0x%x, read 0x%x\n", + addr[iloop], data, regVal)); + return 0; + } } } @@ -1648,8 +1749,8 @@ int Feb_Control_ReadRegister(uint32_t offset, uint32_t *retval) { side[iloop], actualOffset)); return 0; } - LOG(logINFO, ("Read 0x%x from %s 0x%x\n", value[iloop], side[iloop], - actualOffset)); + LOG(logDEBUG1, ("Read 0x%x from %s 0x%x\n", value[iloop], + side[iloop], actualOffset)); *retval = value[iloop]; // if not the other (left, not right OR right, not left), return the // value @@ -1824,7 +1925,11 @@ int64_t Feb_Control_Get_RateTable_Period_in_nsec() { int Feb_Control_SetRateCorrectionTau(int64_t tau_in_Nsec) { // period = exptime if 16bit, period = subexptime if 32 bit - int dr = Feb_Control_GetDynamicRange(); + int dr = 0; + if (!Feb_Control_GetDynamicRange(&dr)) { + LOG(logERROR, ("Could not set rate correction tau\n")); + return 0; + } double period_in_sec = (double)(Feb_Control_GetSubFrameExposureTime()) / (double)1e9; if (dr == 16) diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.h b/slsDetectorServers/eigerDetectorServer/FebControl.h index 7ede407ad..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(); @@ -55,7 +54,7 @@ int Feb_Control_ResetChipPartially(); int Feb_Control_SendBitModeToBebServer(); unsigned int Feb_Control_ConvertTimeToRegister(float time_in_sec); int Feb_Control_PrepareForAcquisition(); -void Feb_Control_PrintAcquisitionSetup(); +int Feb_Control_PrintAcquisitionSetup(); int Feb_Control_StartAcquisition(); int Feb_Control_StopAcquisition(); int Feb_Control_IsReadyForTrigger(int *readyForTrigger); @@ -63,8 +62,10 @@ int Feb_Control_SendSoftwareTrigger(); int Feb_Control_SoftwareTrigger(int block); // parameters -int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); -unsigned int Feb_Control_GetDynamicRange(); +int Feb_Control_SetDynamicRange(int dr); +int Feb_Control_GetDynamicRange(int *retval); +int Feb_Control_Disable16bitConversion(int disable); +int Feb_Control_Get16bitConversionDisabled(); int Feb_Control_SetReadoutSpeed(unsigned int readout_speed); int Feb_Control_SetReadoutMode(unsigned int readout_mode); int Feb_Control_SetTriggerMode(unsigned int trigger_mode); @@ -86,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/FebRegisterDefs.h b/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h index db2627181..1ec86f834 100644 --- a/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h +++ b/slsDetectorServers/eigerDetectorServer/FebRegisterDefs.h @@ -29,6 +29,8 @@ #define DAQ_REG_HRDWRE_OW_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_OW_MASTER_OFST) #define DAQ_REG_HRDWRE_MASTER_OFST (4) #define DAQ_REG_HRDWRE_MASTER_MSK (0x00000001 << DAQ_REG_HRDWRE_MASTER_OFST) +#define DAQ_REG_HRDWRE_DSBL_16BIT_OFST (5) +#define DAQ_REG_HRDWRE_DSBL_16BIT_MSK (0x00000001 << DAQ_REG_HRDWRE_DSBL_16BIT_OFST) #define DAQ_REG_HRDWRE_PROGRAM_OFST (30) #define DAQ_REG_HRDWRE_PROGRAM_MSK (0x00000001 << DAQ_REG_HRDWRE_PROGRAM_OFST) #define DAQ_REG_HRDWRE_M8_OFST (31) diff --git a/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer b/slsDetectorServers/eigerDetectorServer/bin/eigerDetectorServer_developer index 8f791e4b0..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 0955523a1..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"); @@ -821,29 +858,38 @@ int readRegister(uint32_t offset, uint32_t *retval) { /* set parameters - dr, roi */ int setDynamicRange(int dr) { - // setting dr - if (dr > 0) { - LOG(logDEBUG1, ("Setting dynamic range: %d\n", dr)); -#ifndef VIRTUAL - sharedMemory_lockLocalLink(); - if (Feb_Control_SetDynamicRange(dr)) { - if (!Beb_SetUpTransferParameters(dr)) { - LOG(logERROR, ("Could not set bit mode in the back end\n")); - sharedMemory_unlockLocalLink(); - return eiger_dynamicrange; - } - } - sharedMemory_unlockLocalLink(); -#endif - eiger_dynamicrange = dr; + if (dr <= 0) { + return FAIL; } - // getting dr -#ifndef VIRTUAL +#ifdef VIRTUAL + LOG(logINFO, ("Setting dynamic range: %d\n", dr)); +#else sharedMemory_lockLocalLink(); - eiger_dynamicrange = Feb_Control_GetDynamicRange(); + if (Feb_Control_SetDynamicRange(dr)) { + if (!Beb_SetUpTransferParameters(dr)) { + LOG(logERROR, ("Could not set bit mode in the back end\n")); + sharedMemory_unlockLocalLink(); + return eiger_dynamicrange; + } + } sharedMemory_unlockLocalLink(); #endif - return eiger_dynamicrange; + eiger_dynamicrange = dr; + return OK; +} + +int getDynamicRange(int *retval) { +#ifdef VIRTUAL + *retval = eiger_dynamicrange; +#else + sharedMemory_lockLocalLink(); + if (!Feb_Control_GetDynamicRange(retval)) { + sharedMemory_unlockLocalLink(); + return FAIL; + } + sharedMemory_unlockLocalLink(); +#endif + return OK; } /* parameters - readout */ @@ -1158,6 +1204,7 @@ int setModule(sls_detector_module myMod, char *mess) { // if quad, set M8 and PROGRAM manually if (!Feb_Control_SetChipSignalsToTrimQuad(1)) { + sharedMemory_unlockLocalLink(); return FAIL; } @@ -1170,6 +1217,7 @@ int setModule(sls_detector_module myMod, char *mess) { // if quad, reset M8 and PROGRAM manually if (!Feb_Control_SetChipSignalsToTrimQuad(0)) { + sharedMemory_unlockLocalLink(); return FAIL; } @@ -1179,6 +1227,7 @@ int setModule(sls_detector_module myMod, char *mess) { // if quad, reset M8 and PROGRAM manually if (!Feb_Control_SetChipSignalsToTrimQuad(0)) { + sharedMemory_unlockLocalLink(); return FAIL; } @@ -1450,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; @@ -1923,7 +2085,8 @@ int setRateCorrection( else if (custom_tau_in_nsec == -1) custom_tau_in_nsec = Feb_Control_Get_RateTable_Tau_in_nsec(); - int dr = Feb_Control_GetDynamicRange(); + int dr = eiger_dynamicrange; + // get period = subexptime if 32bit , else period = exptime if 16 bit int64_t actual_period = Feb_Control_GetSubFrameExposureTime(); // already in nsec @@ -2321,7 +2484,7 @@ void *start_timer(void *arg) { const int maxRows = MAX_ROWS_PER_READOUT; const int packetsPerFrame = (maxPacketsPerFrame * readNRows) / maxRows; - LOG(logDEBUG1, + LOG(logDEBUG, (" dr:%d\n bytesperpixel:%f\n tgenable:%d\n datasize:%d\n " "packetsize:%d\n maxnumpackes:%d\n npixelsx:%d\n databytes:%d\n", dr, bytesPerPixel, tgEnable, datasize, packetsize, maxPacketsPerFrame, @@ -2338,11 +2501,13 @@ void *start_timer(void *arg) { npixels /= 2; } LOG(logDEBUG1, - ("pixels:%d pixelsperpacket:%d\n", npixels, pixelsPerPacket)); + ("npixels:%d pixelsperpacket:%d\n", npixels, pixelsPerPacket)); + uint8_t *src = (uint8_t *)imageData; for (int i = 0; i < npixels; ++i) { if (i > 0 && i % pixelsPerPacket == 0) { ++pixelVal; } + switch (dr) { case 4: *((uint8_t *)(imageData + i)) = @@ -2357,6 +2522,30 @@ void *start_timer(void *arg) { *((uint8_t *)(imageData + i)) = eiger_virtual_test_mode ? 0xFE : (uint8_t)pixelVal; break; + case 12: + if (eiger_virtual_test_mode) { + // first 12 bit pixel + // first 8 byte + *src++ = 0xFE; + // second 12bit pixel + ++i; + // second 8 byte + *src++ = 0xEF; + // third byte + *src++ = 0xFF; + } else { + // first 12 bit pixel + // first 8 byte + *src++ = (uint8_t)(i & 0xFF); + // second 8 byte (first nibble) + *src = (uint8_t)((i++ >> 8u) & 0xF); + // second 12bit pixel + // second 8 byte (second nibble) + *src++ |= ((uint8_t)(i & 0xF) << 4u); + // third byte + *src++ = (uint8_t)((i >> 4u) & 0xFF); + } + break; case 16: *((uint16_t *)(imageData + i * sizeof(uint16_t))) = eiger_virtual_test_mode ? 0xFFE : (uint16_t)pixelVal; @@ -2433,9 +2622,27 @@ void *start_timer(void *arg) { // fill data int dstOffset = sizeof(sls_detector_header); int dstOffset2 = sizeof(sls_detector_header); - { - for (int psize = 0; psize < datasize; psize += npixelsx) { + if (dr == 12) { + // multiple of 768,1024,4096 + int copysize = 256; + for (int psize = 0; psize < datasize; psize += copysize) { + memcpy(packetData + dstOffset, imageData + srcOffset, + copysize); + memcpy(packetData2 + dstOffset2, imageData + srcOffset2, + copysize); + srcOffset += copysize; + srcOffset2 += copysize; + dstOffset += copysize; + dstOffset2 += copysize; + // reached 1 row (quarter module) + if ((srcOffset % npixelsx) == 0) { + srcOffset += npixelsx; + srcOffset2 += npixelsx; + } + } + } else { + for (int psize = 0; psize < datasize; psize += npixelsx) { if (dr == 32 && tgEnable == 0) { memcpy(packetData + dstOffset, imageData + srcOffset, npixelsx / 2); @@ -2733,9 +2940,9 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { int calculateDataBytes() { if (send_to_ten_gig) - return setDynamicRange(-1) * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE; + return eiger_dynamicrange * ONE_GIGA_CONSTANT * TEN_GIGA_BUFFER_SIZE; else - return setDynamicRange(-1) * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE; + return eiger_dynamicrange * TEN_GIGA_CONSTANT * ONE_GIGA_BUFFER_SIZE; } int getTotalNumberOfChannels() { diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h index 95a1590b1..cca94c3fd 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorServer_defs.h @@ -5,7 +5,7 @@ #define LINKED_SERVER_NAME "eigerDetectorServer" -#define REQUIRED_FIRMWARE_VERSION (29) +#define REQUIRED_FIRMWARE_VERSION (30) // virtual ones renamed for consistency // real ones keep previous name for compatibility (already in production) #ifdef VIRTUAL diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index c107dc4e9..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 da7576ef8..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() { @@ -952,7 +998,16 @@ void resetPeripheral() { /* set parameters - dr, roi */ -int setDynamicRange(int dr) { return DYNAMIC_RANGE; } +int setDynamicRange(int dr) { + if (dr == 16) + return OK; + return FAIL; +} + +int getDynamicRange(int *retval) { + *retval = DYNAMIC_RANGE; + return OK; +} /* parameters - timer */ void setNumFrames(int64_t val) { @@ -1442,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 @@ -1921,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 2c7fa59a7..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 362bf2079..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 @@ -788,7 +839,16 @@ void setMasterSlaveConfiguration() { /* set parameters - dr, roi */ -int setDynamicRange(int dr) { return DYNAMIC_RANGE; } +int setDynamicRange(int dr) { + if (dr == 16) + return OK; + return FAIL; +} + +int getDynamicRange(int *retval) { + *retval = DYNAMIC_RANGE; + return OK; +} int setROI(ROI arg) { @@ -1238,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 7c35d3cb0..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 dc8e1ea28..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) { @@ -796,7 +812,16 @@ void resetPeripheral() { /* set parameters - dr, roi */ -int setDynamicRange(int dr) { return DYNAMIC_RANGE; } +int setDynamicRange(int dr) { + if (dr == 16) + return OK; + return FAIL; +} + +int getDynamicRange(int *retval) { + *retval = DYNAMIC_RANGE; + return OK; +} void setADCInvertRegister(uint32_t val) { LOG(logINFO, ("Setting ADC Port Invert Reg to 0x%x\n", val)); diff --git a/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer b/slsDetectorServers/moenchDetectorServer/bin/moenchDetectorServer_developer index c3e6c2e41..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 05bd7e62d..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 */ @@ -706,7 +712,16 @@ void resetPeripheral() { /* set parameters - dr, adcenablemask */ -int setDynamicRange(int dr) { return DYNAMIC_RANGE; } +int setDynamicRange(int dr) { + if (dr == 16) + return OK; + return FAIL; +} + +int getDynamicRange(int *retval) { + *retval = DYNAMIC_RANGE; + return OK; +} int setADCEnableMask(uint32_t mask) { if (mask == 0u) { diff --git a/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer b/slsDetectorServers/mythen3DetectorServer/bin/mythen3DetectorServer_developer index 4b4c158f1..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 f4b40499e..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() { @@ -729,46 +767,54 @@ void resetPeripheral() { /* set parameters - dr, roi */ int setDynamicRange(int dr) { - if (dr > 0) { - uint32_t regval = 0; - switch (dr) { - /*case 1: TODO:Not implemented in firmware yet - regval = CONFIG_DYNAMIC_RANGE_1_VAL; - break;*/ - case 8: - regval = CONFIG_DYNAMIC_RANGE_8_VAL; - break; - case 16: - regval = CONFIG_DYNAMIC_RANGE_16_VAL; - break; - case 32: - regval = CONFIG_DYNAMIC_RANGE_24_VAL; - break; - default: - LOG(logERROR, ("Invalid dynamic range %d\n", dr)); - return -1; - } - // set it - bus_w(CONFIG_REG, bus_r(CONFIG_REG) & ~CONFIG_DYNAMIC_RANGE_MSK); - bus_w(CONFIG_REG, bus_r(CONFIG_REG) | regval); - updatePacketizing(); + if (dr <= 0) { + return FAIL; } + uint32_t regval = 0; + switch (dr) { + /*case 1: TODO:Not implemented in firmware yet + regval = CONFIG_DYNAMIC_RANGE_1_VAL; + break;*/ + case 8: + regval = CONFIG_DYNAMIC_RANGE_8_VAL; + break; + case 16: + regval = CONFIG_DYNAMIC_RANGE_16_VAL; + break; + case 32: + regval = CONFIG_DYNAMIC_RANGE_24_VAL; + break; + default: + LOG(logERROR, ("Invalid dynamic range %d\n", dr)); + return -1; + } + // set it + bus_w(CONFIG_REG, bus_r(CONFIG_REG) & ~CONFIG_DYNAMIC_RANGE_MSK); + bus_w(CONFIG_REG, bus_r(CONFIG_REG) | regval); + updatePacketizing(); + return OK; +} +int getDynamicRange(int *retval) { uint32_t regval = bus_r(CONFIG_REG) & CONFIG_DYNAMIC_RANGE_MSK; switch (regval) { /*case CONFIG_DYNAMIC_RANGE_1_VAL: TODO:Not implemented in firmware yet return 1;*/ case CONFIG_DYNAMIC_RANGE_8_VAL: - return 8; + *retval = 8; + break; case CONFIG_DYNAMIC_RANGE_16_VAL: - return 16; + *retval = 16; + break; case CONFIG_DYNAMIC_RANGE_24_VAL: - return 32; + *retval = 32; + break; default: LOG(logERROR, ("Invalid dynamic range %d read back\n", regval >> CONFIG_DYNAMIC_RANGE_OFST)); - return -1; + return FAIL; } + return OK; } /* set parameters - readout */ @@ -1091,7 +1137,8 @@ void updatePacketizing() { // 10g if (tgEnable) { - const int dr = setDynamicRange(-1); + int dr = 0; + getDynamicRange(&dr); packetsPerFrame = 1; if (dr == 32 && ncounters > 1) { packetsPerFrame = 2; @@ -1545,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; @@ -2202,7 +2253,8 @@ void *start_timer(void *arg) { const int imageSize = calculateDataBytes(); const int tgEnable = enableTenGigabitEthernet(-1); - const int dr = setDynamicRange(-1); + int dr = 0; + getDynamicRange(&dr); int ncounters = __builtin_popcount(getCounterMask()); int dataSize = 0; int packetsPerFrame = 0; @@ -2523,7 +2575,8 @@ int copyModule(sls_detector_module *destMod, sls_detector_module *srcMod) { int calculateDataBytes() { int numCounters = __builtin_popcount(getCounterMask()); - int dr = setDynamicRange(-1); + int dr = 0; + getDynamicRange(&dr); return (NCHAN_1_COUNTER * NCHIP * numCounters * ((double)dr / 8.00)); } diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 955f35e6b..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 @@ -173,6 +184,7 @@ void setMasterSlaveConfiguration(); // parameters - dr, roi int setDynamicRange(int dr); +int getDynamicRange(int *retval); #ifdef GOTTHARDD int setROI(ROI arg); ROI getROI(); @@ -362,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 f94b2345a..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) { @@ -2815,6 +2819,9 @@ int set_dynamic_range(int file_des) { #endif #if defined(EIGERD) || defined(MYTHEN3D) case 8: +#ifdef EIGERD + case 12: +#endif case 16: case 32: #endif @@ -2822,14 +2829,25 @@ int set_dynamic_range(int file_des) { defined(MOENCHD) || defined(GOTTHARD2D) case 16: #endif - retval = setDynamicRange(dr); - LOG(logDEBUG1, ("Dynamic range: %d\n", retval)); - if (retval == -1) { - ret = FAIL; - sprintf(mess, "Could not get dynamic range.\n"); - LOG(logERROR, (mess)); + if (dr >= 0) { + ret = setDynamicRange(dr); + if (ret == FAIL) { + sprintf(mess, "Could not set dynamic range to %d\n", dr); + LOG(logERROR, (mess)); + } + } + + // get + if (ret == OK) { + ret = getDynamicRange(&retval); + if (ret == FAIL) { + strcpy(mess, "Could not get dynamic range\n"); + LOG(logERROR, (mess)); + } else { + LOG(logDEBUG1, ("Dynamic range: %d\n", retval)); + validate(&ret, mess, dr, retval, "set dynamic range", DEC); + } } - validate(&ret, mess, dr, retval, "set dynamic range", DEC); break; default: modeNotImplemented("Dynamic range", dr); @@ -3977,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)); } } @@ -4650,11 +4665,17 @@ int set_read_n_rows(int file_des) { LOG(logERROR, (mess)); } else { #ifdef EIGERD - int dr = setDynamicRange(GET_FLAG); + int dr = 0; + ret = getDynamicRange(&dr); int isTenGiga = enableTenGigabitEthernet(GET_FLAG); unsigned int maxnl = MAX_ROWS_PER_READOUT; unsigned int maxnp = (isTenGiga ? 4 : 16) * dr; - if ((arg * maxnp) % maxnl) { + // get dr fail + if (ret == FAIL) { + strcpy(mess, + "Could not read n rows (failed to get dynamic range)\n"); + LOG(logERROR, (mess)); + } else if ((arg * maxnp) % maxnl) { ret = FAIL; sprintf(mess, "Could not set number of rows to %d. For %d bit " @@ -4862,6 +4883,7 @@ int is_udp_configured() { LOG(logWARNING, ("%s", configureMessage)); return FAIL; } + // virtual: no check (can be eth name: lo, ip: 127.0.0.1) #ifndef VIRTUAL if (udpDetails[i].dstmac == 0) { sprintf(configureMessage, @@ -7111,7 +7133,10 @@ int get_receiver_parameters(int file_des) { } // dynamic range - i32 = setDynamicRange(GET_FLAG); + ret = getDynamicRange(&i32); + if (ret == FAIL) { + i32 = 0; + } n += sendData(file_des, &i32, sizeof(i32), INT32); if (n < 0) return printSocketReadError(); @@ -8193,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)); @@ -9673,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 ba10ac797..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; ///@} @@ -284,7 +290,7 @@ class Detector { Result getDynamicRange(Positions pos = {}) const; /** - * [Eiger] Options: 4, 8, 16, 32. If i is 32, also sets clkdivider to 2, + * [Eiger] Options: 4, 8, 12, 16, 32. If i is 32, also sets clkdivider to 2, * else sets clkdivider to 1 \n [Mythen3] Options: 8, 16, 32 \n * [Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16 */ @@ -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 b0c8ee303..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}, @@ -1109,7 +1111,6 @@ class CmdProxy { /* acquisition parameters */ std::string Acquire(int action); std::string Exptime(int action); - std::string DynamicRange(int action); std::string ReadoutSpeed(int action); std::string Adcphase(int action); std::string Dbitphase(int action); @@ -1281,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( @@ -1328,7 +1335,7 @@ class CmdProxy { dr, getDynamicRange, setDynamicRange, StringTo, "[value]\n\tDynamic Range or number of bits per " "pixel in detector.\n\t" - "[Eiger] Options: 4, 8, 16, 32. If set to 32, also sets " + "[Eiger] Options: 4, 8, 12, 16, 32. If set to 32, also sets " "clkdivider to 2, else to 0.\n\t" "[Mythen3] Options: 8, 16, 32\n\t" "[Jungfrau][Gotthard][Ctb][Moench][Mythen3][Gotthard2] 16"); @@ -1901,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 025370bf7..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); } @@ -387,7 +404,7 @@ void Detector::setDynamicRange(int value) { std::vector Detector::getDynamicRangeList() const { switch (getDetectorType().squash()) { case defs::EIGER: - return std::vector{4, 8, 16, 32}; + return std::vector{4, 8, 12, 16, 32}; case defs::MYTHEN3: return std::vector{8, 16, 32}; default: @@ -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/slsReceiverSoftware/src/ClientInterface.cpp b/slsReceiverSoftware/src/ClientInterface.cpp index 9fa919359..5c3e8af36 100644 --- a/slsReceiverSoftware/src/ClientInterface.cpp +++ b/slsReceiverSoftware/src/ClientInterface.cpp @@ -716,6 +716,7 @@ int ClientInterface::set_dynamic_range(Interface &socket) { break; */ case 4: + case 12: if (detType == EIGER) { exists = true; } diff --git a/slsReceiverSoftware/src/HDF5DataFile.cpp b/slsReceiverSoftware/src/HDF5DataFile.cpp index 758d70d7b..0ffe0d525 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.cpp +++ b/slsReceiverSoftware/src/HDF5DataFile.cpp @@ -112,6 +112,7 @@ void HDF5DataFile::CreateFirstHDF5DataFile( udpPortNumber_ = udpPortNumber; switch (dynamicRange_) { + case 12: case 16: dataType_ = PredType::STD_U16LE; break; @@ -248,8 +249,30 @@ void HDF5DataFile::WriteToFile(char *buffer, const int buffersize, WriteParameterDatasets(currentFrameNumber, (sls_receiver_header *)(buffer)); } +void HDF5DataFile::Convert12to16Bit(uint16_t *dst, uint8_t *src) { + for (int i = 0; i < EIGER_NUM_PIXELS; ++i) { + *dst = (uint16_t)(*src++ & 0xFF); + *dst++ |= (uint16_t)((*src & 0xF) << 8u); + ++i; + *dst = (uint16_t)((*src++ & 0xF0) >> 4u); + *dst++ |= (uint16_t)((*src++ & 0xFF) << 4u); + } +} + void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber, char *buffer) { + // expand 12 bit to 16 bits + char *revBuffer = buffer; + if (dynamicRange_ == 12) { + revBuffer = (char *)malloc(EIGER_16_BIT_IMAGE_SIZE); + if (revBuffer == nullptr) { + throw sls::RuntimeError("Could not allocate memory for 12 bit to " + "16 bit conversion in object " + + std::to_string(index_)); + } + Convert12to16Bit((uint16_t *)revBuffer, (uint8_t *)buffer); + } + std::lock_guard lock(*hdf5Lib_); uint64_t nDimx = @@ -266,9 +289,15 @@ void HDF5DataFile::WriteDataFile(const uint64_t currentFrameNumber, dataSpace_->selectHyperslab(H5S_SELECT_SET, count, start); DataSpace memspace(2, dims2); - dataSet_->write(buffer, dataType_, memspace, *dataSpace_); + dataSet_->write(revBuffer, dataType_, memspace, *dataSpace_); memspace.close(); + if (dynamicRange_ == 12) { + free(revBuffer); + } } catch (const Exception &error) { + if (dynamicRange_ == 12) { + free(revBuffer); + } LOG(logERROR) << "Could not write to file in object " << index_; error.printErrorStack(); throw sls::RuntimeError("Could not write to file in object " + diff --git a/slsReceiverSoftware/src/HDF5DataFile.h b/slsReceiverSoftware/src/HDF5DataFile.h index a2e2aa78a..dc1c2ae5e 100644 --- a/slsReceiverSoftware/src/HDF5DataFile.h +++ b/slsReceiverSoftware/src/HDF5DataFile.h @@ -35,6 +35,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { private: void CreateFile(); + void Convert12to16Bit(uint16_t *dst, uint8_t *src); void WriteDataFile(const uint64_t currentFrameNumber, char *buffer); void WriteParameterDatasets(const uint64_t currentFrameNumber, sls_receiver_header *rheader); @@ -72,4 +73,7 @@ class HDF5DataFile : private virtual slsDetectorDefs, public File { int detIndex_{0}; int numUnitsPerReadout_{0}; uint32_t udpPortNumber_{0}; + + static const int EIGER_NUM_PIXELS{256 * 2 * 256}; + static const int EIGER_16_BIT_IMAGE_SIZE{EIGER_NUM_PIXELS * 2}; }; \ No newline at end of file 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