diff --git a/RELEASE.txt b/RELEASE.txt index dcd4f14d8..1d0d4b021 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -164,6 +164,13 @@ This document describes the differences between 6.0.0 and 5.2.0 releases. This will only affect shared memory and will not try to change the current tcp port of the control/stop server in detector. + 26. [Eiger][Jungfrau][Gotthard2] Speed + Command line: readoutspeed, API: getReadoutSpeed/ setReadoutSpeed + Previous command: speed, setSpeed/ getSpeed + [Eiger][Jungfrau] same as before. + [Gotthard2] New command to set readout speed. Options: 108, 144 (in MHz) + Added Detector::getReadoutSpeedList to get enums for each detector. + Detector servers ---------------- diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index eb44e5aaa..56f586b19 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -690,7 +690,7 @@ void setupDetector() { eiger_photonenergy = DEFAULT_PHOTON_ENERGY; setParallelMode(DEFAULT_PARALLEL_MODE); setOverFlowMode(DEFAULT_READOUT_OVERFLOW32_MODE); - setClockDivider(RUN_CLK, DEFAULT_CLK_SPEED); // clk_devider,half speed + setReadoutSpeed(DEFAULT_CLK_SPEED); setIODelay(DEFAULT_IO_DELAY); setTiming(DEFAULT_TIMING_MODE); setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER); @@ -1712,11 +1712,7 @@ int enableTenGigabitEthernet(int val) { } /* eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter */ -int setClockDivider(enum CLKINDEX ind, int val) { - if (ind != RUN_CLK) { - LOG(logERROR, ("Unknown clock index: %d\n", ind)); - return FAIL; - } +int setReadoutSpeed(int val) { if (val >= 0) { LOG(logINFO, ("Setting Read out Speed: %d\n", val)); #ifndef VIRTUAL @@ -1732,12 +1728,9 @@ int setClockDivider(enum CLKINDEX ind, int val) { return OK; } -int getClockDivider(enum CLKINDEX ind) { - if (ind != RUN_CLK) { - LOG(logERROR, ("Unknown clock index: %d\n", ind)); - return FAIL; - } - return eiger_readoutspeed; +int getReadoutSpeed(int* retval) { + *retval = eiger_readoutspeed; + return OK; } int setIODelay(int val) { diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 9d7fd73bb..39c95f0d5 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -2083,6 +2083,32 @@ int getVCOFrequency(enum CLKINDEX ind) { return ALTERA_PLL_C10_GetVCOFrequency(pllIndex); } +int setReadoutSpeed(int val) { + switch (val) +} + +int getReadoutSpeed(int* retval) { +//TODO ASIC and ADIFreg need to check???? +// clkdiv 2, 3, 4, 5? + if (clkDivider[READOUT_C0] == SPEED_108_CLKDIV_0 && + clkDivider[READOUT_C1] == SPEED_108_CLKDIV_1 && + getPhase(READOUT_C0, 1) == SPEED_108_CLKPHASE_DEG_1) { + *retval = G_108MHZ; + } + + else if (clkDivider[READOUT_C0] == SPEED_144_CLKDIV_0 && + clkDivider[READOUT_C1] == SPEED_144_CLKDIV_1 && + getPhase(READOUT_C0, 1) == SPEED_144_CLKPHASE_DEG_1) { + *retval = G_144MHZ; + } + + else { + *retval = -1; + return FAIL; + } + return OK; +} + int getMaxClockDivider() { return ALTERA_PLL_C10_GetMaxClockDivider(); } int setClockDivider(enum CLKINDEX ind, int val) { diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index 6046fba9e..18a935c24 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -59,6 +59,14 @@ #define DEFAULT_SYSTEM_C2 (5) //(144444448) // sync_clk, 144 MHz #define DEFAULT_SYSTEM_C3 (5) //(144444448) // str_clk, 144 MHz +#define DEFAULT_READOUT_SPEED (G_108MHz) +#define SPEED_144_CLKDIV_0 (6) +#define SPEED_144_CLKDIV_1 (6) +#define SPEED_144_CLKPHASE_DEG_1 (125) +#define SPEED_108_CLKDIV_0 (8) +#define SPEED_108_CLKDIV_1 (8) +#define SPEED_108_CLKPHASE_DEG_1 (270) + /* Firmware Definitions */ #define FIXED_PLL_FREQUENCY (20000000) // 20MHz #define INT_SYSTEM_C0_FREQUENCY (144000000) // 144 MHz diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c index 5ffd80ed3..9fa401ba6 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -457,7 +457,7 @@ void setupDetector() { return; } - setClockDivider(RUN_CLK, HALF_SPEED); + setReadoutSpeed(HALF_SPEED); cleanFifos(); resetCore(); @@ -487,8 +487,6 @@ void setupDetector() { // not applicable for chipv1.1 setStorageCellDelay(DEFAULT_STRG_CLL_DLY); } - /*setClockDivider(RUN_CLK, HALF_SPEED); depends if all the previous stuff - * works*/ setTiming(DEFAULT_TIMING_MODE); setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER); @@ -1823,11 +1821,7 @@ void configureASICTimer() { ASIC_CTRL_DS_TMR_VAL); } -int setClockDivider(enum CLKINDEX ind, int val) { - if (ind != RUN_CLK) { - LOG(logERROR, ("Unknown clock index %d to set speed\n", ind)); - return FAIL; - } +int setReadoutSpeed(int val) { // stop state machine if running if (runBusy()) { stopStateMachine(); @@ -1923,23 +1917,21 @@ int setClockDivider(enum CLKINDEX ind, int val) { return OK; } -int getClockDivider(enum CLKINDEX ind) { - if (ind != RUN_CLK) { - LOG(logERROR, ("Unknown clock index %d to get speed\n", ind)); - return -1; - } +int getReadoutSpeed(int* retval) { u_int32_t speed = bus_r(CONFIG_REG) & CONFIG_READOUT_SPEED_MSK; switch (speed) { case CONFIG_FULL_SPEED_40MHZ_VAL: - return FULL_SPEED; + *retval = FULL_SPEED; case CONFIG_HALF_SPEED_20MHZ_VAL: - return HALF_SPEED; + *retval = HALF_SPEED; case CONFIG_QUARTER_SPEED_10MHZ_VAL: - return QUARTER_SPEED; + retval = QUARTER_SPEED; default: LOG(logERROR, ("Unknown speed val: %d\n", speed)); - return -1; + *retval == -1; + return FAIL; } + return OK; } int setPhase(enum CLKINDEX ind, int val, int degrees) { diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index cc0a97938..42645c97f 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -470,8 +470,8 @@ int autoCompDisable(int on); int setComparatorDisableTime(int64_t val); int64_t getComparatorDisableTime(); void configureASICTimer(); -int setClockDivider(enum CLKINDEX ind, int val); -int getClockDivider(enum CLKINDEX ind); +int setReadoutSpeed(int val); +int getReadoutSpeed(int* retval); int setPhase(enum CLKINDEX ind, int val, int degrees); int getPhase(enum CLKINDEX ind, int degrees); int getMaxPhase(enum CLKINDEX ind); @@ -495,8 +495,8 @@ uint64_t getSelectCurrentSource(); // eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter #elif EIGERD -int setClockDivider(enum CLKINDEX ind, int val); -int getClockDivider(enum CLKINDEX ind); +int setReadoutSpeed(int val); +int getReadoutSpeed(int* retval); int setIODelay(int val); int setCounterBit(int val); int pulsePixel(int n, int x, int y); @@ -548,6 +548,8 @@ int validatePhaseinDegrees(enum CLKINDEX ind, int val, int retval); // void setFrequency(enum CLKINDEX ind, int val); int getFrequency(enum CLKINDEX ind); int getVCOFrequency(enum CLKINDEX ind); +int setReadoutSpeed(int val); +int getReadoutSpeed(int* retval); int getMaxClockDivider(); int setClockDivider(enum CLKINDEX ind, int val); int getClockDivider(enum CLKINDEX ind); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index bedad75f6..8c662c724 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -272,4 +272,6 @@ int set_dest_udp_list(int); int get_num_dest_list(int); int clear_all_udp_dst(int); int get_udp_first_dest(int); -int set_udp_first_dest(int); \ No newline at end of file +int set_udp_first_dest(int); +int get_readout_speed(int); +int set_readout_speed(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 5c724b10e..ba6531b74 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -410,7 +410,8 @@ void function_table() { flist[F_CLEAR_ALL_UDP_DEST] = &clear_all_udp_dst; flist[F_GET_UDP_FIRST_DEST] = &get_udp_first_dest; flist[F_SET_UDP_FIRST_DEST] = &set_udp_first_dest; - + flist[F_GET_READOUT_SPEED] = &get_readout_speed; + flist[F_SET_READOUT_SPEED] = &set_readout_speed; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { LOG(logERROR, ("The last detector function enum has reached its " @@ -6010,46 +6011,21 @@ int set_clock_divider(int file_des) { return printSocketReadError(); LOG(logDEBUG1, ("Setting clock (%d) divider: %u\n", args[0], args[1])); -#if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(GOTTHARD2D) && \ - !defined(MYTHEN3D) +#if !defined(GOTTHARD2D) && !defined(MYTHEN3D) functionNotImplemented(); #else // only set if (Server_VerifyLock() == OK) { - int ind = args[0]; - int val = args[1]; - enum CLKINDEX c = 0; - switch (ind) { - // specific clock index -#if defined(EIGERD) || defined(JUNGFRAUD) - case RUN_CLOCK: - c = RUN_CLK; - break; -#endif - default: - // any clock index -#if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (ind < NUM_CLOCKS) { - c = (enum CLKINDEX)ind; - break; - } -#endif - modeNotImplemented("clock index (divider set)", ind); - break; - } - // validate val range - if (ret != FAIL) { -#ifdef JUNGFRAUD - if (val == (int)FULL_SPEED && isHardwareVersion2()) { - ret = FAIL; - strcpy(mess, - "Full speed not implemented for this board version.\n"); - LOG(logERROR, (mess)); - } else -#endif -#if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (val < 2 || val > getMaxClockDivider()) { + if (args[0] >= NUM_CLOCKS) { + modeNotImplemented("clock index (divider set)", args[0]); + } + + if (ret == OK) { + enum CLKINDEX c = (enum CLKINDEX)args[0]; + int val = args[1]; + // validate val range + if (val < 2 || val > getMaxClockDivider()) { char *clock_names[] = {CLK_NAMES}; ret = FAIL; sprintf(mess, @@ -6058,24 +6034,12 @@ int set_clock_divider(int file_des) { clock_names[c], (int)c, val, getMaxClockDivider()); LOG(logERROR, (mess)); } -#else - if (val < (int)FULL_SPEED || val > (int)QUARTER_SPEED) { - ret = FAIL; - sprintf(mess, - "Cannot set speed to %d. Value should be in range " - "[%d-%d]\n", - val, (int)FULL_SPEED, (int)QUARTER_SPEED); - LOG(logERROR, (mess)); - } -#endif } if (ret != FAIL) { - char modeName[50] = "speed"; -#if defined(GOTTHARD2D) || defined(MYTHEN3D) + char modeName[50]; char *clock_names[] = {CLK_NAMES}; sprintf(modeName, "%s clock (%d) divider", clock_names[c], (int)c); -#endif if (getClockDivider(c) == val) { LOG(logINFO, ("Same %s: %d\n", modeName, val)); } else { @@ -6105,29 +6069,15 @@ int get_clock_divider(int file_des) { return printSocketReadError(); LOG(logDEBUG1, ("Getting clock (%d) divider\n", arg)); -#if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(GOTTHARD2D) && \ - !defined(MYTHEN3D) +#if !defined(GOTTHARD2D) && !defined(MYTHEN3D) functionNotImplemented(); #else // get only - enum CLKINDEX c = 0; - switch (arg) { -#if defined(EIGERD) || defined(JUNGFRAUD) - case RUN_CLOCK: - c = RUN_CLK; - break; -#endif - default: -#if defined(GOTTHARD2D) || defined(MYTHEN3D) - if (arg < NUM_CLOCKS) { - c = (enum CLKINDEX)arg; - break; - } -#endif - modeNotImplemented("clock index (divider get)", arg); - break; - } + if (arg >= NUM_CLOCKS) { + modeNotImplemented("clock index (divider set)", arg); + } if (ret == OK) { + enum CLKINDEX c = (enum CLKINDEX)arg; retval = getClockDivider(c); char *clock_names[] = {CLK_NAMES}; LOG(logDEBUG1, ("retval %s clock (%d) divider: %d\n", clock_names[c], @@ -9288,3 +9238,81 @@ int set_udp_first_dest(int file_des) { #endif return Server_SendResult(file_des, INT32, NULL, 0); } + + +int get_readout_speed(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; + LOG(logDEBUG1, ("Getting readout speed\n")); + +#if !defined(JUNGFRAU) && !defined(EIGER) && !defined(GOTTHARD2D) + functionNotImplemented(); +#else + // get only + ret = getReadoutSpeed(&retval); + LOG(logDEBUG1, ("retval readout speed: %d\n", retval)); + if (ret == FAIL) { + strcpy(mess, "Could not get readout speed\n"); + LOG(logERROR, (mess)); + } +#endif + return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); +} + +int set_readout_speed(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 readout speed : %u\n", arg)); + +#if !defined(JUNGFRAU) && !defined(EIGER) && !defined(GOTTHARD2D) + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { +#ifdef JUNGFRAUD + if (arg == (int)FULL_SPEED && isHardwareVersion2()) { + ret = FAIL; + strcpy(mess, + "Full speed not implemented for this board version (v1.0).\n"); + LOG(logERROR, (mess)); + } +#endif + if (ret == OK) { + switch (arg) { +#if defined(EIGERD) || !defined(JUNGFRAUD) + case FULL_SPEED: + case HALF_SPEED: + case QUARTER_SPEED: +#elif GOTTHARD2D + case G_108MHZ: + case G_144MHZ: +#endif + break; + default: + modeNotImplemented("readout speed index", arg); + break; + } + ret = setReadoutSpeed(arg); + if (ret == FAIL) { + sprintf(mess, "Could not set readout speed to %d.\n", arg); + LOG(logERROR, (mess)); + } else { + ret = getReadoutSpeed(&retval); + LOG(logDEBUG1, ("retval readout speed: %d\n", retval)); + if (ret == FAIL) { + strcpy(mess, "Could not get readout speed\n"); + LOG(logERROR, (mess)); + } + validate(&ret, mess, arg, retval, "set readout speed", 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 c6fc5867d..39636aedc 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -300,16 +300,20 @@ class Detector { /** list of possible timing modes for this detector */ std::vector getTimingModeList() const; - /** [Eiger][Jungfrau] */ - Result getSpeed(Positions pos = {}) const; + /** [Eiger][Jungfrau][Gotthard2] */ + Result getReadoutSpeed(Positions pos = {}) const; - /** [Eiger][Jungfrau] - * Options: FULL_SPEED, HALF_SPEED, QUARTER_SPEED \n - * [Jungfrau] FULL_SPEED option only available from v2.0 boards and with - * setting number of interfaces to 2. \n Also overwrites adcphase to + /** [Eiger][Jungfrau][Gotthard2] + * [Jungfrau] Options: FULL_SPEED, HALF_SPEED (Default), QUARTER_SPEED \n + * [Eiger] Options: FULL_SPEED (Default), HALF_SPEED, QUARTER_SPEED \n + * [Gotthard2] Options: G_108MHZ (Default), G_144MHZ \n + * [Jungfrau] FULL_SPEED option only available from v2.0 boards \n Also overwrites adcphase to * recommended default. */ - void setSpeed(defs::speedLevel value, Positions pos = {}); + void setReadoutSpeed(defs::speedLevel value, Positions pos = {}); + + /** list of possible readoutspeed modes for this detector */ + std::vector getReadoutSpeedList() const; /** [Jungfrau][CTB][Moench] */ Result getADCPhase(Positions pos = {}) const; diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 1cfff609d..4f276ebe0 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -605,32 +605,33 @@ std::string CmdProxy::Exptime(int action) { return os.str(); } -std::string CmdProxy::Speed(int action) { +std::string CmdProxy::ReadoutSpeed(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[0 or full_speed|1 or half_speed|2 or " - "quarter_speed]\n\t[Eiger][Jungfrau] Readout speed of " - "chip.\n\t[Jungfrau] FULL_SPEED option only available from v2.0 " - "boards and with setting number of interfaces to 2. Also " - "overwrites adcphase to recommended default. " + os << "\n\t[0 or full_speed|1 or half_speed|2 or " + "quarter_speed]\n\t\t[Eiger][Jungfrau] Readout " + "speed of chip.\n\t\t[Eiger] Default speed is full_speed." + "\n\t\t[Jungfrau] Default speed is half_speed. full_speed " + "option only available from v2.0 boards. Also overwrites " + "adcphase to recommended default.\n\t [144|108]\n\t\t[Gotthard2] " + "Readout speed of chip in MHz. Default is 108." << '\n'; } else { defs::detectorType type = det->getDetectorType().squash(); if (type == defs::CHIPTESTBOARD || type == defs::MOENCH) { throw sls::RuntimeError( - "Speed not implemented. Did you mean runclk?"); + "ReadoutSpeed not implemented. Did you mean runclk?"); } - if (type != defs::EIGER && type != defs::JUNGFRAU) { + if (type != defs::EIGER && type != defs::JUNGFRAU && type != defs::GOTTHARD2) { throw sls::RuntimeError( - "Speed not implemented."); // setspped one function problem. tbr - // after change + "ReadoutSpeed not implemented."); } if (action == defs::GET_ACTION) { if (!args.empty()) { WrongNumberOfParameters(0); } - auto t = det->getSpeed(std::vector{det_id}); + auto t = det->getReadoutSpeed(std::vector{det_id}); os << OutString(t) << '\n'; } else if (action == defs::PUT_ACTION) { if (args.size() != 1) { @@ -655,7 +656,7 @@ std::string CmdProxy::Speed(int action) { } catch (...) { t = sls::StringTo(args[0]); } - det->setSpeed(t, std::vector{det_id}); + det->setReadoutSpeed(t, std::vector{det_id}); os << sls::ToString(t) << '\n'; // no args to convert 0,1,2 as well } else { throw sls::RuntimeError("Unknown action"); diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 2424f89cd..eaf94819c 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -591,7 +591,8 @@ class CmdProxy { /* acquisition parameters */ {"cycles", "triggers"}, {"cyclesl", "triggersl"}, - {"clkdivider", "speed"}, + {"clkdivider", "readoutspeed"}, + {"speed", "readoutspeed"}, {"vhighvoltage", "highvoltage"}, {"digitest", "imagetest"}, {"filter", "filterresistor"}, @@ -792,7 +793,7 @@ class CmdProxy { {"drlist", &CmdProxy::drlist}, {"timing", &CmdProxy::timing}, {"timinglist", &CmdProxy::timinglist}, - {"speed", &CmdProxy::Speed}, + {"speed", &CmdProxy::ReadoutSpeed}, {"adcphase", &CmdProxy::Adcphase}, {"maxadcphaseshift", &CmdProxy::maxadcphaseshift}, {"dbitphase", &CmdProxy::Dbitphase}, @@ -1097,7 +1098,7 @@ class CmdProxy { std::string Acquire(int action); std::string Exptime(int action); std::string DynamicRange(int action); - std::string Speed(int action); + std::string ReadoutSpeed(int action); std::string Adcphase(int action); std::string Dbitphase(int action); std::string ClockFrequency(int action); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 4bdbbe0ff..ec58f3a7a 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -412,20 +412,31 @@ std::vector Detector::getTimingModeList() const { } } -Result Detector::getSpeed(Positions pos) const { - auto res = pimpl->Parallel(&Module::getClockDivider, pos, defs::RUN_CLOCK); - Result speedResult(res.size()); - for (unsigned int i = 0; i < res.size(); ++i) { - speedResult[i] = static_cast(res[i]); - } - return speedResult; +Result Detector::getReadoutSpeed(Positions pos) const { + return pimpl->Parallel(&Module::getReadoutSpeed, pos); } -void Detector::setSpeed(defs::speedLevel value, Positions pos) { - pimpl->Parallel(&Module::setClockDivider, pos, defs::RUN_CLOCK, - static_cast(value)); +void Detector::setReadoutSpeed(defs::speedLevel value, Positions pos) { + pimpl->Parallel(&Module::getReadoutSpeed, pos, value); } + +std::vector Detector::getReadoutSpeedList() const { + switch (getDetectorType().squash()) { + case defs::EIGER: + case defs::JUNGFRAU: + return std::vector{defs::FULL_SPEED, + defs::HALF_SPEED, + defs::QUARTER_SPEED}; + case defs::GOTTHARD2: + return std::vector{defs::G_108MHZ, + defs::G_144MHZ}; + default: + throw RuntimeError("Readout speed not implemented for this detector"); + } +} + + Result Detector::getADCPhase(Positions pos) const { return pimpl->Parallel(&Module::getClockPhase, pos, defs::ADC_CLOCK, false); } diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index c14cd84e1..71cae1b63 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -600,6 +600,14 @@ void Module::setTimingMode(timingMode value) { } } +slsDetectorDefs::speedLevel Module::getReadoutSpeed() const { + return sendToDetector(F_GET_READOUT_SPEED); +} + +void Module::setReadoutSpeed(speedLevel value) { + sendToDetector(F_SET_READOUT_SPEED, value); +} + int Module::getClockDivider(int clkIndex) const { return sendToDetector(F_GET_CLOCK_DIVIDER, clkIndex); } diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 67e4b0327..bdc8c8f79 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -144,6 +144,8 @@ class Module : public virtual slsDetectorDefs { void setDynamicRange(int dr); timingMode getTimingMode() const; void setTimingMode(timingMode value); + speedLevel getReadoutSpeed() const; + void setReadoutSpeed(speedLevel value); int getClockDivider(int clkIndex) const; void setClockDivider(int clkIndex, int value); int getClockPhase(int clkIndex, bool inDegrees) const; diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index e72ae63ba..45cff407b 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -889,54 +889,84 @@ TEST_CASE("timinglist", "[.cmd]") { REQUIRE_THROWS(proxy.Call("timinglist", {}, -1, PUT)); } -TEST_CASE("speed", "[.cmd]") { +TEST_CASE("readoutspeed", "[.cmd]") { Detector det; CmdProxy proxy(&det); auto det_type = det.getDetectorType().squash(); - if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) { - auto prev_val = det.getSpeed(); - // full speed for jungfrau only works for new boards - /* + if (det_type == defs::EIGER || det_type == defs::JUNGFRAU || det_type == defs::GOTTHARD2) { + auto prev_val = det.getReadoutSpeed(); + + // full speed for jungfrau only works for new boards (chipv1.1 is with new board [hw1.0 and chipv1.0 not tested here]) + if ((det_type == defs::JUNGFRAU && det.getChipVersion().squash() * 10 == 11) || (det_type == defs::EIGER)) { std::ostringstream oss1, oss2, oss3, oss4; - proxy.Call("speed", {"0"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "speed full_speed\n"); - proxy.Call("speed", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "speed full_speed\n"); - proxy.Call("speed", {"full_speed"}, -1, PUT, oss3); - REQUIRE(oss3.str() == "speed full_speed\n"); - proxy.Call("speed", {}, -1, GET, oss4); - REQUIRE(oss4.str() == "speed full_speed\n"); + proxy.Call("readoutspeed", {"0"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "readoutspeed full_speed\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "readoutspeed full_speed\n"); + proxy.Call("readoutspeed", {"full_speed"}, -1, PUT, oss3); + REQUIRE(oss3.str() == "readoutspeed full_speed\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss4); + REQUIRE(oss4.str() == "readoutspeed full_speed\n"); } - */ - { - std::ostringstream oss1, oss2, oss3, oss4; - proxy.Call("speed", {"1"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "speed half_speed\n"); - proxy.Call("speed", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "speed half_speed\n"); - proxy.Call("speed", {"half_speed"}, -1, PUT, oss3); - REQUIRE(oss3.str() == "speed half_speed\n"); - proxy.Call("speed", {}, -1, GET, oss4); - REQUIRE(oss4.str() == "speed half_speed\n"); + + if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) { + { + std::ostringstream oss1, oss2, oss3, oss4; + proxy.Call("readoutspeed", {"1"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "readoutspeed half_speed\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "readoutspeed half_speed\n"); + proxy.Call("readoutspeed", {"half_speed"}, -1, PUT, oss3); + REQUIRE(oss3.str() == "readoutspeed half_speed\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss4); + REQUIRE(oss4.str() == "readoutspeed half_speed\n"); + } + { + std::ostringstream oss1, oss2, oss3, oss4; + proxy.Call("readoutspeed", {"2"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "readoutspeed quarter_speed\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "readoutspeed quarter_speed\n"); + proxy.Call("readoutspeed", {"quarter_speed"}, -1, PUT, oss3); + REQUIRE(oss3.str() == "readoutspeed quarter_speed\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss4); + REQUIRE(oss4.str() == "readoutspeed quarter_speed\n"); + } + REQUIRE_THROWS(proxy.Call("readoutspeed", {"108"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {"144"}, -1, PUT)); } - { - std::ostringstream oss1, oss2, oss3, oss4; - proxy.Call("speed", {"2"}, -1, PUT, oss1); - REQUIRE(oss1.str() == "speed quarter_speed\n"); - proxy.Call("speed", {}, -1, GET, oss2); - REQUIRE(oss2.str() == "speed quarter_speed\n"); - proxy.Call("speed", {"quarter_speed"}, -1, PUT, oss3); - REQUIRE(oss3.str() == "speed quarter_speed\n"); - proxy.Call("speed", {}, -1, GET, oss4); - REQUIRE(oss4.str() == "speed quarter_speed\n"); + + if (det_type == defs::GOTTHARD2) { + { + std::ostringstream oss1, oss2, oss3, oss4; + proxy.Call("readoutspeed", {"108"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "readoutspeed 108\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "readoutspeed 108\n"); + } + + { + std::ostringstream oss1, oss2, oss3, oss4; + proxy.Call("readoutspeed", {"144"}, -1, PUT, oss1); + REQUIRE(oss1.str() == "readoutspeed 144\n"); + proxy.Call("readoutspeed", {}, -1, GET, oss2); + REQUIRE(oss2.str() == "readoutspeed 144\n"); + } + REQUIRE_THROWS(proxy.Call("readoutspeed", {"full_speed"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {"half_speed"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {"quarter_speed"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {"0"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {"1"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {"2"}, -1, PUT)); } + for (int i = 0; i != det.size(); ++i) { - det.setSpeed(prev_val[i], {i}); + det.setReadoutSpeed(prev_val[i], {i}); } } else { - REQUIRE_THROWS(proxy.Call("speed", {"0"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("speed", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {"0"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("readoutspeed", {}, -1, GET)); } } diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index e2f6cab32..af924c1cd 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -377,7 +377,7 @@ typedef struct { enum readoutMode { ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL }; /** chip speed */ - enum speedLevel { FULL_SPEED, HALF_SPEED, QUARTER_SPEED }; + enum speedLevel { FULL_SPEED, HALF_SPEED, QUARTER_SPEED, G_108MHZ, G_144MHZ }; /** * burst mode for gotthard2 diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index f6215dce6..4b1952ec8 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -249,6 +249,8 @@ enum detFuncs { F_CLEAR_ALL_UDP_DEST, F_GET_UDP_FIRST_DEST, F_SET_UDP_FIRST_DEST, + F_GET_READOUT_SPEED, + F_SET_READOUT_SPEED, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -602,7 +604,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_CLEAR_ALL_UDP_DEST: return "F_CLEAR_ALL_UDP_DEST"; case F_GET_UDP_FIRST_DEST: return "F_GET_UDP_FIRST_DEST"; case F_SET_UDP_FIRST_DEST: return "F_SET_UDP_FIRST_DEST"; - + case F_GET_READOUT_SPEED: return "F_GET_READOUT_SPEED"; + case F_SET_READOUT_SPEED: return "F_SET_READOUT_SPEED"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index 5441f2e67..c22406be8 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -247,6 +247,10 @@ std::string ToString(const defs::speedLevel s) { return std::string("half_speed"); case defs::QUARTER_SPEED: return std::string("quarter_speed"); + case defs::G_108MHZ: + return std::string("108"); + case defs::G_144MHZ: + return std::string("144"); default: return std::string("Unknown"); } @@ -707,6 +711,10 @@ template <> defs::speedLevel StringTo(const std::string &s) { return defs::HALF_SPEED; if (s == "quarter_speed") return defs::QUARTER_SPEED; + if (s == "108") + return defs::G_108MHZ; + if (s == "144") + return defs::G_144MHZ; throw sls::RuntimeError("Unknown speed " + s); }