diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index 9079c932e..c7c6c39ca 100755 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -11,6 +11,7 @@ pybind11_add_module(_slsdet src/current.cpp src/duration.cpp src/DurationWrapper.cpp + src/pedestal.cpp ) target_link_libraries(_slsdet PUBLIC diff --git a/python/examples/use_pedestalmode.py b/python/examples/use_pedestalmode.py new file mode 100644 index 000000000..ad209bf2d --- /dev/null +++ b/python/examples/use_pedestalmode.py @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: LGPL-3.0-or-other +# Copyright (C) 2021 Contributors to the SLS Detector Package +from slsdet import Detector, pedestalParameters + +p = pedestalParameters() +p.frames = 10 +p.loops= 20 + + + +d = Detector() +d.pedestalmode = p \ No newline at end of file diff --git a/python/setup.py b/python/setup.py index 47c732e82..aee81b640 100755 --- a/python/setup.py +++ b/python/setup.py @@ -35,6 +35,7 @@ ext_modules = [ 'src/scan.cpp', 'src/duration.cpp', 'src/DurationWrapper.cpp', + 'src/pedestal.cpp', ] diff --git a/python/slsdet/__init__.py b/python/slsdet/__init__.py index dd657ecf8..fc25dd9b3 100755 --- a/python/slsdet/__init__.py +++ b/python/slsdet/__init__.py @@ -27,4 +27,5 @@ IpAddr = _slsdet.IpAddr MacAddr = _slsdet.MacAddr scanParameters = _slsdet.scanParameters currentSrcParameters = _slsdet.currentSrcParameters -DurationWrapper = _slsdet.DurationWrapper \ No newline at end of file +DurationWrapper = _slsdet.DurationWrapper +pedestalParameters = _slsdet.pedestalParameters \ No newline at end of file diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 4d4820919..9fc0581d2 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -2866,7 +2866,27 @@ class Detector(CppDetectorApi): @filtercells.setter def filtercells(self, value): ut.set_using_dict(self.setNumberOfFilterCells, value) + + @property + @element + def pedestalmode(self): + """ + [Jungfrau] Enables or disables pedestal mode. Pass in a pedestalParameters object + see python/examples/use_pedestalmode.py + Note + ---- + The number of frames or triggers is overwritten by #pedestal_frames x pedestal_loops x 2. \n + In auto timing mode or in trigger mode with #frames > 1, #frames is overwritten and #triggers = 1, else #triggers is overwritten and #frames = 1. \n + One cannot set #frames, #triggers or timing mode in pedestal mode (exception thrown).\n + Disabling pedestal mode will set back the normal mode values of #frames and #triggers." + """ + return self.getPedestalMode() + + @pedestalmode.setter + def pedestalmode(self, value): + ut.set_using_dict(self.setPedestalMode, value) + @property def maxclkphaseshift(self): """ diff --git a/python/src/detector.cpp b/python/src/detector.cpp index b69019f12..cbee09c77 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1270,6 +1270,16 @@ void init_det(py::module &m) { (void (Detector::*)(int, sls::Positions)) & Detector::setNumberOfFilterCells, py::arg(), py::arg() = Positions{}); + CppDetectorApi.def( + "getPedestalMode", + (Result(Detector::*)(sls::Positions) const) & + Detector::getPedestalMode, + py::arg() = Positions{}); + CppDetectorApi.def( + "setPedestalMode", + (void (Detector::*)(const defs::pedestalParameters, sls::Positions)) & + Detector::setPedestalMode, + py::arg(), py::arg() = Positions{}); CppDetectorApi.def("getROI", (Result(Detector::*)(sls::Positions) const) & Detector::getROI, diff --git a/python/src/main.cpp b/python/src/main.cpp index 9144b2315..901c4900e 100644 --- a/python/src/main.cpp +++ b/python/src/main.cpp @@ -19,6 +19,8 @@ void init_pattern(py::module &); void init_scan(py::module &); void init_source(py::module &); void init_duration(py::module &); +void init_pedestal(py::module &); + PYBIND11_MODULE(_slsdet, m) { m.doc() = R"pbdoc( C/C++ API @@ -37,6 +39,7 @@ PYBIND11_MODULE(_slsdet, m) { init_scan(m); init_source(m); init_duration(m); + init_pedestal(m); // init_experimental(m); py::module io = m.def_submodule("io", "Submodule for io"); diff --git a/python/src/pedestal.cpp b/python/src/pedestal.cpp new file mode 100644 index 000000000..b956f7252 --- /dev/null +++ b/python/src/pedestal.cpp @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: LGPL-3.0-or-other +// Copyright (C) 2021 Contributors to the SLS Detector Package + +#include "py_headers.h" + +#include "sls/ToString.h" +#include "sls/sls_detector_defs.h" + +namespace py = pybind11; +void init_pedestal(py::module &m) { + + using src = slsDetectorDefs::pedestalParameters; + py::class_ pedestalParameters(m, "pedestalParameters"); + + pedestalParameters.def(py::init()); + pedestalParameters.def_readwrite("enable", &src::enable); + pedestalParameters.def_readwrite("frames", &src::frames); + pedestalParameters.def_readwrite("loops", &src::loops); + pedestalParameters.def(pybind11::self == pybind11::self); + + pedestalParameters.def("__repr__", + [](const src &a) { return sls::ToString(a); }); +} diff --git a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h index 488fbdc09..e00358c91 100644 --- a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h +++ b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h @@ -255,6 +255,17 @@ #define PLL_CNTRL_ADDR_OFST (16) #define PLL_CNTRL_ADDR_MSK (0x0000003F << PLL_CNTRL_ADDR_OFST) + +/* Pedestal Mode Regiser */ +#define PEDESTAL_MODE_REG (0x57 << MEM_MAP_SHIFT) + +#define PEDESTAL_MODE_ITRTNS_OFST (0) +#define PEDESTAL_MODE_ITRTNS_MSK (0x0000FFFF << PEDESTAL_MODE_ITRTNS_OFST) +#define PEDESTAL_MODE_LNGTH_OFST (16) +#define PEDESTAL_MODE_LNGTH_MSK (0x000000FF << PEDESTAL_MODE_LNGTH_OFST) +#define PEDESTAL_MODE_ENBLE_OFST (31) +#define PEDESTAL_MODE_ENBLE_MSK (0x00000001 << PEDESTAL_MODE_ENBLE_OFST) + /* Config Register for chip 1.1 */ #define CONFIG_V11_REG (0x58 << MEM_MAP_SHIFT) diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 7665ed8a3..30f790a2b 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 898e1cd12..73379083d 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -55,6 +55,9 @@ int32_t clkPhase[NUM_CLOCKS] = {}; int detPos[4] = {}; int chipConfigured = 0; +uint64_t normal_mode_frames = -1; +uint64_t normal_mode_triggers = -1; + int isInitCheckDone() { return initCheckDone; } int getInitResult(char **mess) { @@ -555,6 +558,13 @@ void setupDetector() { setFlipRows(DEFAULT_FLIP_ROWS); setReadNRows(MAX_ROWS_PER_READOUT); } +#ifdef VIRTUAL + // setting pedestalmode depends on previous values + bus_w(PEDESTAL_MODE_REG, + bus_r(PEDESTAL_MODE_REG) & ~PEDESTAL_MODE_ENBLE_MSK); +#endif + setPedestalMode(DEFAULT_PEDESTAL_MODE, DEFAULT_PEDESTAL_FRAMES, + DEFAULT_PEDESTAL_LOOPS); } int resetToDefaultDacs(int hardReset) { @@ -975,6 +985,9 @@ int getNextFrameNumber(uint64_t *retval) { } void setNumFrames(int64_t val) { + if (getPedestalMode()) { + return; + } if (val > 0) { LOG(logINFO, ("Setting number of frames %lld\n", (long long int)val)); set64BitReg(val, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); @@ -986,6 +999,9 @@ int64_t getNumFrames() { } void setNumTriggers(int64_t val) { + if (getPedestalMode()) { + return; + } if (val > 0) { LOG(logINFO, ("Setting number of triggers %lld\n", (long long int)val)); set64BitReg(val, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); @@ -1439,6 +1455,9 @@ void setSynchronization(int enable) { } void setTiming(enum timingMode arg) { + if (getPedestalMode()) { + return; + } switch (arg) { case AUTO_TIMING: LOG(logINFO, ("Set Timing: Auto\n")); @@ -2513,6 +2532,81 @@ uint64_t getSelectCurrentSource() { } } +int getPedestalMode() { + return ((bus_r(PEDESTAL_MODE_REG) & PEDESTAL_MODE_ENBLE_MSK) >> + PEDESTAL_MODE_ENBLE_OFST); +} + +void getPedestalParameters(uint8_t *frames, uint16_t *loops) { + uint32_t addr = PEDESTAL_MODE_REG; + *frames = + ((bus_r(addr) & PEDESTAL_MODE_LNGTH_MSK) >> PEDESTAL_MODE_LNGTH_OFST); + *loops = ((bus_r(PEDESTAL_MODE_REG) & PEDESTAL_MODE_ITRTNS_MSK) >> + PEDESTAL_MODE_ITRTNS_OFST); +} + +void setPedestalMode(int enable, uint8_t frames, uint16_t loops) { + int prevPedestalEnable = getPedestalMode(); + uint32_t addr = PEDESTAL_MODE_REG; + + if (enable) { + LOG(logINFOBLUE, ("Enabling pedestal mode [frames: %hhu, loops: %hu]\n", + frames, loops)); + // enable + bus_w(addr, bus_r(addr) | PEDESTAL_MODE_ENBLE_MSK); + // frames + bus_w(addr, bus_r(addr) & ~PEDESTAL_MODE_LNGTH_MSK); + bus_w(addr, bus_r(addr) | ((frames << PEDESTAL_MODE_LNGTH_OFST) & + PEDESTAL_MODE_LNGTH_MSK)); + // loops + bus_w(addr, bus_r(addr) & ~PEDESTAL_MODE_ITRTNS_MSK); + bus_w(addr, bus_r(addr) | ((loops << PEDESTAL_MODE_ITRTNS_OFST) & + PEDESTAL_MODE_ITRTNS_MSK)); + + // if it was switched off before, remember the #frames and #triggers + if (prevPedestalEnable == 0) { + normal_mode_frames = getNumFrames(); + normal_mode_triggers = getNumTriggers(); + LOG(logINFO, ("\tRemembering Normal mode #frames and " + "#triggers[%lld, %lld]\n", + normal_mode_frames, normal_mode_triggers)); + } + + // overwrite #frames and #triggers to new values + int64_t expFrames = -1; + int64_t expTriggers = -1; + enum timingMode timing = getTiming(); + if (timing == AUTO_TIMING || + (timing == TRIGGER_EXPOSURE && normal_mode_frames > 1)) { + expFrames = frames * loops * 2; + expTriggers = 1; + } else { + expFrames = 1; + expTriggers = frames * loops * 2; + } + LOG(logINFO, ("\tOverwriting [#frames: %lld, #triggers: %lld]\n", + expFrames, expTriggers)); + set64BitReg(expFrames, SET_FRAMES_LSB_REG, SET_FRAMES_MSB_REG); + set64BitReg(expTriggers, SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); + + } else { + LOG(logINFOBLUE, ("Disabling pedestal mode\n")); + bus_w(addr, bus_r(addr) & ~PEDESTAL_MODE_ENBLE_MSK); + + // if it was switched on before, reset the normal mode #frames and + // #triggers + if (prevPedestalEnable == 1) { + LOG(logINFO, + ("\tResetting to Normal mode [#frames:%lld, #triggers:%lld\n", + normal_mode_frames, normal_mode_triggers)); + set64BitReg(normal_mode_frames, SET_FRAMES_LSB_REG, + SET_FRAMES_MSB_REG); + set64BitReg(normal_mode_triggers, SET_CYCLES_LSB_REG, + SET_CYCLES_MSB_REG); + } + } +} + int getTenGigaFlowControl() { return ((bus_r(CONFIG_REG) & CONFIG_ETHRNT_FLW_CNTRL_MSK) >> CONFIG_ETHRNT_FLW_CNTRL_OFST); diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h index e0e0afd16..2d0033822 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -5,8 +5,8 @@ #include "sls/sls_detector_defs.h" #define MIN_REQRD_VRSN_T_RD_API 0x171220 -#define REQRD_FRMWRE_VRSN_BOARD2 0x230516 // 1.0 pcb (version = 010) -#define REQRD_FRMWRE_VRSN 0x230515 // 2.0 pcb (version = 011) +#define REQRD_FRMWRE_VRSN_BOARD2 0x230920 // 1.0 pcb (version = 010) +#define REQRD_FRMWRE_VRSN 0x230921 // 2.0 pcb (version = 011) #define NUM_HARDWARE_VERSIONS (2) #define HARDWARE_VERSION_NUMBERS \ @@ -52,6 +52,9 @@ #define DEFAULT_FLIP_ROWS (0) #define DEFAULT_FILTER_RESISTOR (1) // higher resistor #define DEFAULT_FILTER_CELL (0) +#define DEFAULT_PEDESTAL_MODE (0) +#define DEFAULT_PEDESTAL_FRAMES (1) +#define DEFAULT_PEDESTAL_LOOPS (1) #define HIGHVOLTAGE_MIN (60) #define HIGHVOLTAGE_MAX (200) diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index bac457945..d7858498f 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -556,6 +556,9 @@ int getCurrentSource(); int getFixCurrentSource(); int getNormalCurrentSource(); uint64_t getSelectCurrentSource(); +int getPedestalMode(); +void getPedestalParameters(uint8_t *frames, uint16_t *loops); +void setPedestalMode(int enable, uint8_t frames, uint16_t loops); #endif // eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index fcb819060..4bf70907f 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -327,3 +327,5 @@ int getRow(); int setRow(int); int getColumn(); int setColumn(int); +int get_pedestal_mode(int); +int set_pedestal_mode(int); diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 5d1631207..9cbc8b4da 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -486,6 +486,8 @@ void function_table() { flist[F_SET_ROW] = &set_row; flist[F_GET_COLUMN] = &get_column; flist[F_SET_COLUMN] = &set_column; + flist[F_GET_PEDESTAL_MODE] = &get_pedestal_mode; + flist[F_SET_PEDESTAL_MODE] = &set_pedestal_mode; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -724,7 +726,18 @@ int set_timing_mode(int file_des) { case GATED: case TRIGGER_GATED: #endif - setTiming(arg); +#if JUNGFRAUD + // cannot set in pedestal mode + if (getPedestalMode()) { + ret = FAIL; + sprintf(mess, + "Cannot set timing mode in pedestal mode. Switch off " + "pedestal mode to change timing mode.\n"); + LOG(logERROR, (mess)); + } +#endif + if (ret == OK) + setTiming(arg); break; default: modeNotImplemented("Timing mode", (int)arg); @@ -1935,57 +1948,59 @@ int acquire(int blocking, int file_des) { #ifdef EIGERD // check for hardware mac and hardware ip if (udpDetails[0].srcmac != getDetectorMAC()) { - ret = FAIL; - uint64_t sourcemac = getDetectorMAC(); - char src_mac[MAC_ADDRESS_SIZE]; - getMacAddressinString(src_mac, MAC_ADDRESS_SIZE, sourcemac); - sprintf(mess, + ret = FAIL; + uint64_t sourcemac = getDetectorMAC(); + char src_mac[MAC_ADDRESS_SIZE]; + getMacAddressinString(src_mac, MAC_ADDRESS_SIZE, sourcemac); + sprintf( + mess, "Invalid udp source mac address for this detector. Must be " "same as hardware detector mac address %s\n", src_mac); - LOG(logERROR, (mess)); - } else if (!enableTenGigabitEthernet(GET_FLAG) && - (udpDetails[0].srcip != getDetectorIP())) { - ret = FAIL; - uint32_t sourceip = getDetectorIP(); - char src_ip[INET_ADDRSTRLEN]; - getIpAddressinString(src_ip, sourceip); - sprintf(mess, + LOG(logERROR, (mess)); + } else if (!enableTenGigabitEthernet(GET_FLAG) && + (udpDetails[0].srcip != getDetectorIP())) { + ret = FAIL; + uint32_t sourceip = getDetectorIP(); + char src_ip[INET_ADDRSTRLEN]; + getIpAddressinString(src_ip, sourceip); + sprintf( + mess, "Invalid udp source ip address for this detector. Must be " "same as hardware detector ip address %s in 1G readout " "mode \n", src_ip); - LOG(logERROR, (mess)); - } else + LOG(logERROR, (mess)); + } else #endif - if (configured == FAIL) { - ret = FAIL; - strcpy(mess, "Could not start acquisition because "); - strcat(mess, configureMessage); - LOG(logERROR, (mess)); - } else if (sharedMemory_getScanStatus() == RUNNING) { - ret = FAIL; - strcpy(mess, "Could not start acquisition because a scan is " - "already running!\n"); - LOG(logERROR, (mess)); - } else { - memset(scanErrMessage, 0, MAX_STR_LENGTH); - sharedMemory_setScanStop(0); - sharedMemory_setScanStatus(IDLE); // if it was error - if (pthread_create(&pthread_tid, NULL, &start_state_machine, - &blocking)) { + if (configured == FAIL) { ret = FAIL; - strcpy(mess, "Could not start acquisition thread!\n"); + strcpy(mess, "Could not start acquisition because "); + strcat(mess, configureMessage); + LOG(logERROR, (mess)); + } else if (sharedMemory_getScanStatus() == RUNNING) { + ret = FAIL; + strcpy(mess, "Could not start acquisition because a scan is " + "already running!\n"); LOG(logERROR, (mess)); } else { - // wait for blocking always (scan or not) - // non blocking-no scan also wait (for error message) - // non blcoking-scan dont wait (there is scanErrorMessage) - if (blocking || !scan) { - pthread_join(pthread_tid, NULL); + memset(scanErrMessage, 0, MAX_STR_LENGTH); + sharedMemory_setScanStop(0); + sharedMemory_setScanStatus(IDLE); // if it was error + if (pthread_create(&pthread_tid, NULL, &start_state_machine, + &blocking)) { + ret = FAIL; + strcpy(mess, "Could not start acquisition thread!\n"); + LOG(logERROR, (mess)); + } else { + // wait for blocking always (scan or not) + // non blocking-no scan also wait (for error message) + // non blcoking-scan dont wait (there is scanErrorMessage) + if (blocking || !scan) { + pthread_join(pthread_tid, NULL); + } } } - } } return Server_SendResult(file_des, INT32, NULL, 0); } @@ -2211,6 +2226,14 @@ int set_num_frames(int file_des) { (long long unsigned int)arg, MAX_FRAMES_IN_BURST_MODE); LOG(logERROR, (mess)); } +#elif JUNGFRAUD + // cannot set in pedestal mode + if (getPedestalMode()) { + ret = FAIL; + sprintf(mess, "Cannot set frames in pedestal mode. It is " + "overwritten anyway.\n"); + LOG(logERROR, (mess)); + } #endif if (ret == OK) { setNumFrames(arg); @@ -2247,10 +2270,22 @@ int set_num_triggers(int file_des) { // only set if (Server_VerifyLock() == OK) { - setNumTriggers(arg); - int64_t retval = getNumTriggers(); - LOG(logDEBUG1, ("retval num triggers %lld\n", (long long int)retval)); - validate64(&ret, mess, arg, retval, "set number of triggers", DEC); +#if JUNGFRAUD + // cannot set in pedestal mode + if (getPedestalMode()) { + ret = FAIL; + sprintf(mess, "Cannot set triggers in pedestal mode. It is " + "overwritten anyway.\n"); + LOG(logERROR, (mess)); + } +#endif + if (ret == OK) { + setNumTriggers(arg); + int64_t retval = getNumTriggers(); + LOG(logDEBUG1, + ("retval num triggers %lld\n", (long long int)retval)); + validate64(&ret, mess, arg, retval, "set number of triggers", DEC); + } } return Server_SendResult(file_des, INT64, NULL, 0); } @@ -7791,62 +7826,20 @@ int set_scan(int file_des) { int stop = args[3]; int step = args[4]; - // disable scan - if (enable == 0) { - LOG(logINFOBLUE, ("Disabling scan")); - scan = 0; - numScanSteps = 0; - // setting number of frames to 1 - int64_t arg = 1; - setNumFrames(arg); - retval = getNumFrames(); - LOG(logDEBUG1, ("retval num frames %lld\n", (long long int)retval)); - validate64(&ret, mess, arg, retval, "set number of frames", DEC); +#ifdef JUNGFRAUD + if (getPedestalMode()) { + ret = FAIL; + strcpy(mess, "Cannot set scan when in pedestal mode.\n"); + LOG(logERROR, (mess)); } - // enable scan - else { - if ((start < stop && step <= 0) || (stop < start && step >= 0)) { - ret = FAIL; - sprintf(mess, "Invalid scan parameters\n"); - LOG(logERROR, (mess)); - } else { - // trimbit scan - if (index == TRIMBIT_SCAN) { - LOG(logINFOBLUE, ("Trimbit scan enabled\n")); - scanTrimbits = 1; - scanGlobalIndex = index; - scanSettleTime_ns = dacTime; - } - // dac scan - else { - // validate index - getDACIndex(index); - if (ret == OK) { - LOG(logINFOBLUE, ("Dac [%d] scan enabled\n", index)); - scanTrimbits = 0; - scanGlobalIndex = index; - scanSettleTime_ns = dacTime; - } - } - } - // valid scan - if (ret == OK) { - scan = 1; - numScanSteps = (abs(stop - start) / abs(step)) + 1; - if (scanSteps != NULL) { - free(scanSteps); - } - scanSteps = malloc(numScanSteps * sizeof(int)); - for (int i = 0; i != numScanSteps; ++i) { - scanSteps[i] = start + i * step; - LOG(logDEBUG1, ("scansteps[%d]:%d\n", i, scanSteps[i])); - } - LOG(logINFOBLUE, ("Enabling scan for %s, start[%d], stop[%d], " - "step[%d], nsteps[%d]\n", - scanTrimbits == 1 ? "trimbits" : "dac", start, - stop, step, numScanSteps)); - - // setting number of frames to scansteps +#endif + if (ret == OK) { + // disable scan + if (enable == 0) { + LOG(logINFOBLUE, ("Disabling scan")); + scan = 0; + numScanSteps = 0; + // setting number of frames to 1 int64_t arg = 1; setNumFrames(arg); retval = getNumFrames(); @@ -7854,7 +7847,63 @@ int set_scan(int file_des) { ("retval num frames %lld\n", (long long int)retval)); validate64(&ret, mess, arg, retval, "set number of frames", DEC); - retval = numScanSteps; + } + // enable scan + else { + if ((start < stop && step <= 0) || + (stop < start && step >= 0)) { + ret = FAIL; + sprintf(mess, "Invalid scan parameters\n"); + LOG(logERROR, (mess)); + } else { + // trimbit scan + if (index == TRIMBIT_SCAN) { + LOG(logINFOBLUE, ("Trimbit scan enabled\n")); + scanTrimbits = 1; + scanGlobalIndex = index; + scanSettleTime_ns = dacTime; + } + // dac scan + else { + // validate index + getDACIndex(index); + if (ret == OK) { + LOG(logINFOBLUE, + ("Dac [%d] scan enabled\n", index)); + scanTrimbits = 0; + scanGlobalIndex = index; + scanSettleTime_ns = dacTime; + } + } + } + // valid scan + if (ret == OK) { + scan = 1; + numScanSteps = (abs(stop - start) / abs(step)) + 1; + if (scanSteps != NULL) { + free(scanSteps); + } + scanSteps = malloc(numScanSteps * sizeof(int)); + for (int i = 0; i != numScanSteps; ++i) { + scanSteps[i] = start + i * step; + LOG(logDEBUG1, ("scansteps[%d]:%d\n", i, scanSteps[i])); + } + LOG(logINFOBLUE, + ("Enabling scan for %s, start[%d], stop[%d], " + "step[%d], nsteps[%d]\n", + scanTrimbits == 1 ? "trimbits" : "dac", start, stop, + step, numScanSteps)); + + // setting number of frames to scansteps + int64_t arg = 1; + setNumFrames(arg); + retval = getNumFrames(); + LOG(logDEBUG1, + ("retval num frames %lld\n", (long long int)retval)); + validate64(&ret, mess, arg, retval, "set number of frames", + DEC); + retval = numScanSteps; + } } } } @@ -10740,4 +10789,108 @@ int setColumn(int value) { memcpy(pos, getDetectorPosition(), sizeof(pos)); pos[X] = value; return setDetectorPosition(pos); -} \ No newline at end of file +} + +int get_pedestal_mode(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retvalEnable = -1; + uint8_t retvalFrames = -1; + uint16_t retvalLoops = -1; + LOG(logDEBUG1, ("Getting pedestal mode\n")); + +#if !defined(JUNGFRAUD) + functionNotImplemented(); +#else + retvalEnable = getPedestalMode(); + getPedestalParameters(&retvalFrames, &retvalLoops); + LOG(logDEBUG1, ("pedestal mode retval: [enable:%d frames:%hhu, " + "loops:%hu]\n", + retvalEnable, retvalFrames, retvalLoops)); +#endif + Server_SendResult(file_des, INT32, NULL, 0); + if (ret != FAIL) { + sendData(file_des, &retvalEnable, sizeof(retvalEnable), INT32); + sendData(file_des, &retvalFrames, sizeof(retvalFrames), OTHER); + sendData(file_des, &retvalLoops, sizeof(retvalLoops), INT16); + } + return ret; +} + +int set_pedestal_mode(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int enable = -1; + uint8_t frames = -1; + uint16_t loops = -1; + + if (receiveData(file_des, &enable, sizeof(enable), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, &frames, sizeof(frames), OTHER) < 0) + return printSocketReadError(); + if (receiveData(file_des, &loops, sizeof(loops), INT16) < 0) + return printSocketReadError(); + LOG(logDEBUG1, ("Setting pedestal mode: enable:%d frames:%hhu, " + "loops:%hu]\n", + enable, frames, loops)); + +#if !defined(JUNGFRAUD) + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + if (check_detector_idle("set pedestal mode") == OK) { + if (enable != 0 && enable != 1) { + ret = FAIL; + sprintf( + mess, + "Could not set pedestal mode. Invalid enable argument %d. " + "Options: [0, 1]\n", + enable); + LOG(logERROR, (mess)); + } else if (enable == 1 && (frames == 0 || loops == 0)) { + ret = FAIL; + sprintf(mess, + "Could not set pedestal mode. Frames and loops cannot " + "be 0. [%hhu, %hu].\n", + frames, loops); + LOG(logERROR, (mess)); + } else { + setPedestalMode(enable, frames, loops); + int retvalEnable = getPedestalMode(); + LOG(logDEBUG1, ("pedestal mode retval: %d\n", retvalEnable)); + if (enable != retvalEnable) { + ret = FAIL; + sprintf( + mess, + "Could not set pedestal mode. Tried to %s, but is %s\n", + (enable ? "enable" : "disable"), + (retvalEnable ? "enabled" : "disabled")); + LOG(logERROR, (mess)); + } + if (enable) { + uint8_t retvalFrames = -1; + uint16_t retvalLoops = -1; + getPedestalParameters(&retvalFrames, &retvalLoops); + LOG(logDEBUG1, + ("pedestal mode retval: [enable:%d frames:%hhu, " + "loops:%hu]\n", + retvalEnable, retvalFrames, retvalLoops)); + if (frames != retvalFrames || loops != retvalLoops) { + ret = FAIL; + sprintf( + mess, + "Could not set pedestal mode. Tried to set " + "[enable: %d, frames: %hhu, loops: %hu], but got " + "[enable: %d, frames: %hhu, loops: %hu].\n", + enable, frames, loops, retvalEnable, retvalFrames, + retvalLoops); + LOG(logERROR, (mess)); + } + } + } + } + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 7c7809208..1ccc1fb05 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1359,6 +1359,20 @@ class Detector { */ void setNumberOfFilterCells(int cell, Positions pos = {}); + /** [Jungfrau] */ + Result getPedestalMode(Positions pos = {}) const; + + /** [Jungfrau] In pedestal mode, the number of frames or triggers is + * overwritten by \n(#pedestal_frames x #pedestal_loops x 2). \nIn + * auto timing mode or in trigger mode with #frames > 1, #frames is + * overwritten and #triggers = 1, \nelse #triggers is overwritten and + * #frames = 1. One cannot set #frames, #triggers or timing mode in pedestal + * mode (it will throw an exception). Disabling pedestal mode will set back + * the original values of #frames and #triggers + */ + void setPedestalMode(const defs::pedestalParameters par, + Positions pos = {}); + ///@} /** @name Gotthard Specific */ diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 25cdce0f2..013d2de24 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -2105,6 +2105,55 @@ std::string CmdProxy::TemperatureEvent(int action) { return os.str(); } +std::string CmdProxy::PedestalMode(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << " [frames] [loops]\n\t\t[Jungfrau] " + "Enable pedestal mode. \n\t\tThe number of frames or triggers is " + "overwritten by: \n\t\t(#pedestal_frames x #pedestal_loops x 2). " + "\n\t\tIn auto timing mode or in trigger mode with #frames > 1, " + "\n\t\t#frames is overwritten and #triggers = 1, \n\t\telse " + "#triggers is overwritten and #frames = 1. \n\t\tOne cannot set " + "#frames, #triggers or timing mode in pedestal mode (exception " + "thrown).\n\n"; + os << cmd + << " [0]\n\t\t[Jungfrau] Disable pedestal " + "mode.\n\t\tDisabling pedestal mode will set back the normal " + "mode values of #frames and #triggers." + << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 0) { + WrongNumberOfParameters(0); + } + auto t = det->getPedestalMode(std::vector{det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + // disable + if (args.size() == 1) { + if (args[0] != "0") { + throw RuntimeError( + "Unknown argument " + args[0] + + ". Did you mean '0' to disable pedestal mode?"); + } + det->setPedestalMode(defs::pedestalParameters()); + } + // enable + else if (args.size() == 2) { + uint8_t frames = StringTo(args[0]); + uint16_t loops = StringTo(args[1]); + det->setPedestalMode(defs::pedestalParameters(frames, loops)); + } else { + throw RuntimeError( + "Invalid number of parareters for this command."); + } + os << ToString(args) << '\n'; + } else { + throw RuntimeError("Unknown action"); + } + return os.str(); +} + /* Gotthard Specific */ std::string CmdProxy::ROI(int action) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index f37f5eb0e..7cc682231 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -1187,6 +1187,7 @@ class CmdProxy { {"storagecell_delay", &CmdProxy::storagecell_delay}, {"gainmode", &CmdProxy::gainmode}, {"filtercells", &CmdProxy::filtercells}, + {"pedestalmode", &CmdProxy::PedestalMode}, /* Gotthard Specific */ {"roi", &CmdProxy::ROI}, @@ -1399,6 +1400,7 @@ class CmdProxy { std::string DataStream(int action); /* Jungfrau Specific */ std::string TemperatureEvent(int action); + std::string PedestalMode(int action); /* Gotthard Specific */ std::string ROI(int action); /* Gotthard2 Specific */ diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 4bcc6f975..4b2a4a77f 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1760,6 +1760,16 @@ void Detector::setNumberOfFilterCells(int cell, Positions pos) { pimpl->Parallel(&Module::setNumberOfFilterCells, pos, cell); } +Result +Detector::getPedestalMode(Positions pos) const { + return pimpl->Parallel(&Module::getPedestalMode, pos); +} + +void Detector::setPedestalMode(const defs::pedestalParameters par, + Positions pos) { + pimpl->Parallel(&Module::setPedestalMode, pos, par); +} + // Gotthard Specific Result Detector::getROI(Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index f14edf354..33603c6ea 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1940,6 +1940,20 @@ void Module::setNumberOfFilterCells(int value) { sendToDetector(F_SET_NUM_FILTER_CELLS, value, nullptr); } +defs::pedestalParameters Module::getPedestalMode() const { + return sendToDetector(F_GET_PEDESTAL_MODE); +} + +void Module::setPedestalMode(const defs::pedestalParameters par) { + sendToDetector(F_SET_PEDESTAL_MODE, par, nullptr); + if (shm()->useReceiverFlag) { + auto value = getNumberOfFrames(); + sendToReceiver(F_RECEIVER_SET_NUM_FRAMES, value, nullptr); + value = getNumberOfTriggers(); + sendToReceiver(F_SET_RECEIVER_NUM_TRIGGERS, value, nullptr); + } +} + // Gotthard Specific slsDetectorDefs::ROI Module::getROI() const { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index a559a7d43..4c3d5a97f 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -419,6 +419,8 @@ class Module : public virtual slsDetectorDefs { void setGainMode(const gainMode mode); int getNumberOfFilterCells() const; void setNumberOfFilterCells(int value); + defs::pedestalParameters getPedestalMode() const; + void setPedestalMode(defs::pedestalParameters par); /************************************************** * * diff --git a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp index af81fd7df..f069a6f5d 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp @@ -506,6 +506,161 @@ TEST_CASE("filtercells", "[.cmd]") { } } +TEST_CASE("pedestalmode", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU) { + auto prev_val = det.getPedestalMode(); + auto prev_frames = det.getNumberOfFrames().tsquash( + "Inconsistent number of frames to test"); + auto prev_triggers = det.getNumberOfTriggers().tsquash( + "Inconsistent number of triggers to test"); + auto prev_timingmode = + det.getTimingMode().tsquash("Inconsistent timing mode to test"); + + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {}, 0, GET)); + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"0"}, -1, GET)); + + REQUIRE_THROWS(proxy.Call("pedestalmode", {"256", "10"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"-1", "10"}, 0, PUT)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"20", "65536"}, 0, PUT)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"20", "-1"}, 0, PUT)); + + { + std::ostringstream oss; + proxy.Call("pedestalmode", {"30", "1000"}, -1, PUT, oss); + REQUIRE(oss.str() == "pedestalmode [30, 1000]\n"); + } + // cannot change any of these in pedestal mode + REQUIRE_THROWS_WITH(proxy.Call("frames", {"200"}, -1, PUT), + "Detector returned: Cannot set frames in pedestal " + "mode. It is overwritten anyway.\n"); + REQUIRE_THROWS_WITH(proxy.Call("triggers", {"200"}, -1, PUT), + "Detector returned: Cannot set triggers in " + "pedestal mode. It is overwritten anyway.\n"); + REQUIRE_THROWS_WITH( + proxy.Call("timing", {"auto"}, -1, PUT), + "Detector returned: Cannot set timing mode in pedestal mode. " + "Switch off pedestal mode to change timing mode.\n"); + REQUIRE_THROWS_WITH( + proxy.Call("scan", {"vb_comp", "500", "1500", "10"}, -1, PUT), + "Detector returned: Cannot set scan when in pedestal mode.\n"); + REQUIRE_THROWS_WITH( + proxy.Call("scan", {"0"}, -1, PUT), + "Detector returned: Cannot set scan when in pedestal mode.\n"); + // should not throw to get these values though + REQUIRE_NOTHROW(proxy.Call("frames", {}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("triggers", {}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("timing", {}, -1, GET)); + REQUIRE_NOTHROW(proxy.Call("scan", {}, -1, GET)); + + { + std::ostringstream oss; + proxy.Call("pedestalmode", {"50", "500"}, -1, PUT, oss); + REQUIRE(oss.str() == "pedestalmode [50, 500]\n"); + } + { + std::ostringstream oss; + proxy.Call("pedestalmode", {}, -1, GET, oss); + REQUIRE(oss.str() == "pedestalmode [enabled, 50, 500]\n"); + } + { + auto pedemode = det.getPedestalMode().tsquash( + "Inconsistent pedestal mode to test"); + REQUIRE(pedemode.enable == true); + REQUIRE(pedemode.frames == 50); + REQUIRE(pedemode.loops == 500); + } + { + std::ostringstream oss; + proxy.Call("pedestalmode", {"0"}, -1, PUT, oss); + REQUIRE(oss.str() == "pedestalmode [0]\n"); + } + { + std::ostringstream oss; + proxy.Call("pedestalmode", {}, -1, GET, oss); + REQUIRE(oss.str() == "pedestalmode [disabled]\n"); + } + + uint8_t pedestalFrames = 50; + uint16_t pedestalLoops = 1000; + int64_t expNumFrames = pedestalFrames * pedestalLoops * 2; + auto origFrames = det.getNumberOfFrames().squash(-1); + auto origTriggers = det.getNumberOfTriggers().squash(-1); + + // auto mode + det.setTimingMode(defs::AUTO_TIMING); + REQUIRE_NOTHROW(proxy.Call( + "pedestalmode", + {std::to_string(pedestalFrames), std::to_string(pedestalLoops)}, -1, + PUT)); + auto numTriggers = det.getNumberOfTriggers().squash(-1); + auto numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == expNumFrames); + REQUIRE(numTriggers == 1); + + // pedestal mode off + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == origFrames); + REQUIRE(numTriggers == origTriggers); + + // trigger mode (frames > 1) + REQUIRE_NOTHROW(det.setTimingMode(defs::TRIGGER_EXPOSURE)); + origFrames = 5; + REQUIRE_NOTHROW(det.setNumberOfFrames(origFrames)); + REQUIRE_NOTHROW(proxy.Call( + "pedestalmode", + {std::to_string(pedestalFrames), std::to_string(pedestalLoops)}, -1, + PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == expNumFrames); + REQUIRE(numTriggers == 1); + + // pedestal mode off + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == origFrames); + REQUIRE(numTriggers == origTriggers); + + // trigger mode (frames = 1) + origFrames = 1; + REQUIRE_NOTHROW(det.setNumberOfFrames(origFrames)); + origTriggers = 10; + REQUIRE_NOTHROW(det.setNumberOfTriggers(origTriggers)); + REQUIRE_NOTHROW(proxy.Call( + "pedestalmode", + {std::to_string(pedestalFrames), std::to_string(pedestalLoops)}, -1, + PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == 1); + REQUIRE(numTriggers == expNumFrames); + + // pedestal mode off + REQUIRE_NOTHROW(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + numTriggers = det.getNumberOfTriggers().squash(-1); + numFrames = det.getNumberOfFrames().squash(-1); + REQUIRE(numFrames == origFrames); + REQUIRE(numTriggers == origTriggers); + + det.setNumberOfFrames(prev_frames); + det.setNumberOfTriggers(prev_triggers); + det.setTimingMode(prev_timingmode); + for (int i = 0; i != det.size(); ++i) { + det.setPedestalMode(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("pedestalmode", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("pedestalmode", {"0"}, -1, PUT)); + } +} + TEST_CASE("sync", "[.cmd]") { Detector det; CmdProxy proxy(&det); diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index 6b784d9c3..efef1161c 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -58,6 +58,9 @@ std::ostream &operator<<(std::ostream &os, std::string ToString(const slsDetectorDefs::currentSrcParameters &r); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::currentSrcParameters &r); +std::string ToString(const slsDetectorDefs::pedestalParameters &r); +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::pedestalParameters &r); const std::string &ToString(const std::string &s); /** Convert std::chrono::duration with specified output unit */ @@ -316,6 +319,7 @@ template <> defs::vetoAlgorithm StringTo(const std::string &s); template <> defs::gainMode StringTo(const std::string &s); template <> defs::polarity StringTo(const std::string &s); +template <> uint8_t StringTo(const std::string &s); template <> uint16_t StringTo(const std::string &s); template <> uint32_t StringTo(const std::string &s); template <> uint64_t StringTo(const std::string &s); diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index a0365818b..a90890a90 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -547,6 +547,29 @@ enum streamingInterface { } } __attribute__((packed)); + struct pedestalParameters { + int enable; + uint8_t frames; + uint16_t loops; + + /** [Jungfrau] disable */ + pedestalParameters() : enable(0), frames(0), loops(0) {} + + /** [Jungfrau] enable */ + pedestalParameters(uint8_t pedestalFrames, uint16_t pedestalLoops) + : enable(1), frames(pedestalFrames), loops(pedestalLoops) { + if (frames == 0 || loops == 0) { + throw sls::RuntimeError( + "Pedestal frames or loops cannot be 0."); + } + } + + bool operator==(const pedestalParameters &other) const { + return ((enable == other.enable) && (frames == other.frames) && + (loops == other.loops)); + } + } __attribute__((packed)); + /** * structure to udpate receiver */ diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index d9005d08e..b0b6de884 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -290,6 +290,8 @@ enum detFuncs { F_SET_ROW, F_GET_COLUMN, F_SET_COLUMN, + F_GET_PEDESTAL_MODE, + F_SET_PEDESTAL_MODE, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 512, /**< detector function should not exceed this @@ -687,6 +689,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_SET_ROW: return "F_SET_ROW"; case F_GET_COLUMN: return "F_GET_COLUMN"; case F_SET_COLUMN: return "F_SET_COLUMN"; + case F_GET_PEDESTAL_MODE: return "F_GET_PEDESTAL_MODE"; + case F_SET_PEDESTAL_MODE: return "F_SET_PEDESTAL_MODE"; 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 c5638ba01..d830030bf 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -4,10 +4,10 @@ #define RELEASE "developer" #define APILIB "developer 0x230224" #define APIRECEIVER "developer 0x230224" -#define APICTB "developer 0x230922" -#define APIGOTTHARD "developer 0x230922" +#define APICTB "developer 0x230922" +#define APIGOTTHARD "developer 0x230922" #define APIGOTTHARD2 "developer 0x230922" -#define APIJUNGFRAU "developer 0x230922" -#define APIMYTHEN3 "developer 0x230922" -#define APIMOENCH "developer 0x230922" -#define APIEIGER "developer 0x230922" +#define APIMYTHEN3 "developer 0x230922" +#define APIMOENCH "developer 0x230922" +#define APIEIGER "developer 0x230922" +#define APIJUNGFRAU "developer 0x230928" diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index e42ce3ebe..66206fe16 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -155,6 +155,23 @@ std::ostream &operator<<(std::ostream &os, return os << ToString(r); } +std::string ToString(const slsDetectorDefs::pedestalParameters &r) { + std::ostringstream oss; + oss << '['; + if (r.enable) + oss << "enabled, " << std::to_string(r.frames) << ", " << r.loops; + else + oss << "disabled"; + + oss << ']'; + return oss.str(); +} + +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::pedestalParameters &r) { + return os << ToString(r); +} + std::string ToString(const defs::runStatus s) { switch (s) { case defs::ERROR: @@ -1083,6 +1100,17 @@ template <> defs::polarity StringTo(const std::string &s) { throw RuntimeError("Unknown polarity mode " + s); } +template <> uint8_t StringTo(const std::string &s) { + int base = s.find("0x") != std::string::npos ? 16 : 10; + int value = std::stoi(s, nullptr, base); + if (value < std::numeric_limits::min() || + value > std::numeric_limits::max()) { + throw RuntimeError("Cannot scan uint8_t from string '" + s + + "'. Value must be in range 0 - 255."); + } + return static_cast(value); +} + template <> uint16_t StringTo(const std::string &s) { int base = s.find("0x") != std::string::npos ? 16 : 10; int value = std::stoi(s, nullptr, base);