changed speed to readoutspeed, added g2 speeds (108, 144)

This commit is contained in:
2021-10-07 18:39:18 +02:00
parent e2aa426966
commit 6b0e6a72df
18 changed files with 299 additions and 173 deletions

View File

@ -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 This will only affect shared memory and will not try to change the
current tcp port of the control/stop server in detector. 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 Detector servers
---------------- ----------------

View File

@ -690,7 +690,7 @@ void setupDetector() {
eiger_photonenergy = DEFAULT_PHOTON_ENERGY; eiger_photonenergy = DEFAULT_PHOTON_ENERGY;
setParallelMode(DEFAULT_PARALLEL_MODE); setParallelMode(DEFAULT_PARALLEL_MODE);
setOverFlowMode(DEFAULT_READOUT_OVERFLOW32_MODE); setOverFlowMode(DEFAULT_READOUT_OVERFLOW32_MODE);
setClockDivider(RUN_CLK, DEFAULT_CLK_SPEED); // clk_devider,half speed setReadoutSpeed(DEFAULT_CLK_SPEED);
setIODelay(DEFAULT_IO_DELAY); setIODelay(DEFAULT_IO_DELAY);
setTiming(DEFAULT_TIMING_MODE); setTiming(DEFAULT_TIMING_MODE);
setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER); setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER);
@ -1712,11 +1712,7 @@ int enableTenGigabitEthernet(int val) {
} }
/* eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter */ /* eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter */
int setClockDivider(enum CLKINDEX ind, int val) { int setReadoutSpeed(int val) {
if (ind != RUN_CLK) {
LOG(logERROR, ("Unknown clock index: %d\n", ind));
return FAIL;
}
if (val >= 0) { if (val >= 0) {
LOG(logINFO, ("Setting Read out Speed: %d\n", val)); LOG(logINFO, ("Setting Read out Speed: %d\n", val));
#ifndef VIRTUAL #ifndef VIRTUAL
@ -1732,12 +1728,9 @@ int setClockDivider(enum CLKINDEX ind, int val) {
return OK; return OK;
} }
int getClockDivider(enum CLKINDEX ind) { int getReadoutSpeed(int* retval) {
if (ind != RUN_CLK) { *retval = eiger_readoutspeed;
LOG(logERROR, ("Unknown clock index: %d\n", ind)); return OK;
return FAIL;
}
return eiger_readoutspeed;
} }
int setIODelay(int val) { int setIODelay(int val) {

View File

@ -2083,6 +2083,32 @@ int getVCOFrequency(enum CLKINDEX ind) {
return ALTERA_PLL_C10_GetVCOFrequency(pllIndex); 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 getMaxClockDivider() { return ALTERA_PLL_C10_GetMaxClockDivider(); }
int setClockDivider(enum CLKINDEX ind, int val) { int setClockDivider(enum CLKINDEX ind, int val) {

View File

@ -59,6 +59,14 @@
#define DEFAULT_SYSTEM_C2 (5) //(144444448) // sync_clk, 144 MHz #define DEFAULT_SYSTEM_C2 (5) //(144444448) // sync_clk, 144 MHz
#define DEFAULT_SYSTEM_C3 (5) //(144444448) // str_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 */ /* Firmware Definitions */
#define FIXED_PLL_FREQUENCY (20000000) // 20MHz #define FIXED_PLL_FREQUENCY (20000000) // 20MHz
#define INT_SYSTEM_C0_FREQUENCY (144000000) // 144 MHz #define INT_SYSTEM_C0_FREQUENCY (144000000) // 144 MHz

View File

@ -457,7 +457,7 @@ void setupDetector() {
return; return;
} }
setClockDivider(RUN_CLK, HALF_SPEED); setReadoutSpeed(HALF_SPEED);
cleanFifos(); cleanFifos();
resetCore(); resetCore();
@ -487,8 +487,6 @@ void setupDetector() {
// not applicable for chipv1.1 // not applicable for chipv1.1
setStorageCellDelay(DEFAULT_STRG_CLL_DLY); setStorageCellDelay(DEFAULT_STRG_CLL_DLY);
} }
/*setClockDivider(RUN_CLK, HALF_SPEED); depends if all the previous stuff
* works*/
setTiming(DEFAULT_TIMING_MODE); setTiming(DEFAULT_TIMING_MODE);
setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER); setNextFrameNumber(DEFAULT_STARTING_FRAME_NUMBER);
@ -1823,11 +1821,7 @@ void configureASICTimer() {
ASIC_CTRL_DS_TMR_VAL); ASIC_CTRL_DS_TMR_VAL);
} }
int setClockDivider(enum CLKINDEX ind, int val) { int setReadoutSpeed(int val) {
if (ind != RUN_CLK) {
LOG(logERROR, ("Unknown clock index %d to set speed\n", ind));
return FAIL;
}
// stop state machine if running // stop state machine if running
if (runBusy()) { if (runBusy()) {
stopStateMachine(); stopStateMachine();
@ -1923,23 +1917,21 @@ int setClockDivider(enum CLKINDEX ind, int val) {
return OK; return OK;
} }
int getClockDivider(enum CLKINDEX ind) { int getReadoutSpeed(int* retval) {
if (ind != RUN_CLK) {
LOG(logERROR, ("Unknown clock index %d to get speed\n", ind));
return -1;
}
u_int32_t speed = bus_r(CONFIG_REG) & CONFIG_READOUT_SPEED_MSK; u_int32_t speed = bus_r(CONFIG_REG) & CONFIG_READOUT_SPEED_MSK;
switch (speed) { switch (speed) {
case CONFIG_FULL_SPEED_40MHZ_VAL: case CONFIG_FULL_SPEED_40MHZ_VAL:
return FULL_SPEED; *retval = FULL_SPEED;
case CONFIG_HALF_SPEED_20MHZ_VAL: case CONFIG_HALF_SPEED_20MHZ_VAL:
return HALF_SPEED; *retval = HALF_SPEED;
case CONFIG_QUARTER_SPEED_10MHZ_VAL: case CONFIG_QUARTER_SPEED_10MHZ_VAL:
return QUARTER_SPEED; retval = QUARTER_SPEED;
default: default:
LOG(logERROR, ("Unknown speed val: %d\n", speed)); 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) { int setPhase(enum CLKINDEX ind, int val, int degrees) {

View File

@ -470,8 +470,8 @@ int autoCompDisable(int on);
int setComparatorDisableTime(int64_t val); int setComparatorDisableTime(int64_t val);
int64_t getComparatorDisableTime(); int64_t getComparatorDisableTime();
void configureASICTimer(); void configureASICTimer();
int setClockDivider(enum CLKINDEX ind, int val); int setReadoutSpeed(int val);
int getClockDivider(enum CLKINDEX ind); int getReadoutSpeed(int* retval);
int setPhase(enum CLKINDEX ind, int val, int degrees); int setPhase(enum CLKINDEX ind, int val, int degrees);
int getPhase(enum CLKINDEX ind, int degrees); int getPhase(enum CLKINDEX ind, int degrees);
int getMaxPhase(enum CLKINDEX ind); int getMaxPhase(enum CLKINDEX ind);
@ -495,8 +495,8 @@ uint64_t getSelectCurrentSource();
// eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter // eiger specific - iodelay, pulse, rate, temp, activate, delay nw parameter
#elif EIGERD #elif EIGERD
int setClockDivider(enum CLKINDEX ind, int val); int setReadoutSpeed(int val);
int getClockDivider(enum CLKINDEX ind); int getReadoutSpeed(int* retval);
int setIODelay(int val); int setIODelay(int val);
int setCounterBit(int val); int setCounterBit(int val);
int pulsePixel(int n, int x, int y); 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); // void setFrequency(enum CLKINDEX ind, int val);
int getFrequency(enum CLKINDEX ind); int getFrequency(enum CLKINDEX ind);
int getVCOFrequency(enum CLKINDEX ind); int getVCOFrequency(enum CLKINDEX ind);
int setReadoutSpeed(int val);
int getReadoutSpeed(int* retval);
int getMaxClockDivider(); int getMaxClockDivider();
int setClockDivider(enum CLKINDEX ind, int val); int setClockDivider(enum CLKINDEX ind, int val);
int getClockDivider(enum CLKINDEX ind); int getClockDivider(enum CLKINDEX ind);

View File

@ -273,3 +273,5 @@ int get_num_dest_list(int);
int clear_all_udp_dst(int); int clear_all_udp_dst(int);
int get_udp_first_dest(int); int get_udp_first_dest(int);
int set_udp_first_dest(int); int set_udp_first_dest(int);
int get_readout_speed(int);
int set_readout_speed(int);

View File

@ -410,7 +410,8 @@ void function_table() {
flist[F_CLEAR_ALL_UDP_DEST] = &clear_all_udp_dst; flist[F_CLEAR_ALL_UDP_DEST] = &clear_all_udp_dst;
flist[F_GET_UDP_FIRST_DEST] = &get_udp_first_dest; flist[F_GET_UDP_FIRST_DEST] = &get_udp_first_dest;
flist[F_SET_UDP_FIRST_DEST] = &set_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 // check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
LOG(logERROR, ("The last detector function enum has reached its " LOG(logERROR, ("The last detector function enum has reached its "
@ -6010,45 +6011,20 @@ int set_clock_divider(int file_des) {
return printSocketReadError(); return printSocketReadError();
LOG(logDEBUG1, ("Setting clock (%d) divider: %u\n", args[0], args[1])); LOG(logDEBUG1, ("Setting clock (%d) divider: %u\n", args[0], args[1]));
#if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(GOTTHARD2D) && \ #if !defined(GOTTHARD2D) && !defined(MYTHEN3D)
!defined(MYTHEN3D)
functionNotImplemented(); functionNotImplemented();
#else #else
// only set // only set
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
int ind = args[0];
int val = args[1]; if (args[0] >= NUM_CLOCKS) {
enum CLKINDEX c = 0; modeNotImplemented("clock index (divider set)", args[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;
} }
if (ret == OK) {
enum CLKINDEX c = (enum CLKINDEX)args[0];
int val = args[1];
// validate val range // 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 (val < 2 || val > getMaxClockDivider()) {
char *clock_names[] = {CLK_NAMES}; char *clock_names[] = {CLK_NAMES};
ret = FAIL; ret = FAIL;
@ -6058,24 +6034,12 @@ int set_clock_divider(int file_des) {
clock_names[c], (int)c, val, getMaxClockDivider()); clock_names[c], (int)c, val, getMaxClockDivider());
LOG(logERROR, (mess)); 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) { if (ret != FAIL) {
char modeName[50] = "speed"; char modeName[50];
#if defined(GOTTHARD2D) || defined(MYTHEN3D)
char *clock_names[] = {CLK_NAMES}; char *clock_names[] = {CLK_NAMES};
sprintf(modeName, "%s clock (%d) divider", clock_names[c], (int)c); sprintf(modeName, "%s clock (%d) divider", clock_names[c], (int)c);
#endif
if (getClockDivider(c) == val) { if (getClockDivider(c) == val) {
LOG(logINFO, ("Same %s: %d\n", modeName, val)); LOG(logINFO, ("Same %s: %d\n", modeName, val));
} else { } else {
@ -6105,29 +6069,15 @@ int get_clock_divider(int file_des) {
return printSocketReadError(); return printSocketReadError();
LOG(logDEBUG1, ("Getting clock (%d) divider\n", arg)); LOG(logDEBUG1, ("Getting clock (%d) divider\n", arg));
#if !defined(EIGERD) && !defined(JUNGFRAUD) && !defined(GOTTHARD2D) && \ #if !defined(GOTTHARD2D) && !defined(MYTHEN3D)
!defined(MYTHEN3D)
functionNotImplemented(); functionNotImplemented();
#else #else
// get only // get only
enum CLKINDEX c = 0; if (arg >= NUM_CLOCKS) {
switch (arg) { modeNotImplemented("clock index (divider set)", 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 (ret == OK) { if (ret == OK) {
enum CLKINDEX c = (enum CLKINDEX)arg;
retval = getClockDivider(c); retval = getClockDivider(c);
char *clock_names[] = {CLK_NAMES}; char *clock_names[] = {CLK_NAMES};
LOG(logDEBUG1, ("retval %s clock (%d) divider: %d\n", clock_names[c], 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 #endif
return Server_SendResult(file_des, INT32, NULL, 0); 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);
}

View File

@ -300,16 +300,20 @@ class Detector {
/** list of possible timing modes for this detector */ /** list of possible timing modes for this detector */
std::vector<defs::timingMode> getTimingModeList() const; std::vector<defs::timingMode> getTimingModeList() const;
/** [Eiger][Jungfrau] */ /** [Eiger][Jungfrau][Gotthard2] */
Result<defs::speedLevel> getSpeed(Positions pos = {}) const; Result<defs::speedLevel> getReadoutSpeed(Positions pos = {}) const;
/** [Eiger][Jungfrau] /** [Eiger][Jungfrau][Gotthard2]
* Options: FULL_SPEED, HALF_SPEED, QUARTER_SPEED \n * [Jungfrau] Options: FULL_SPEED, HALF_SPEED (Default), QUARTER_SPEED \n
* [Jungfrau] FULL_SPEED option only available from v2.0 boards and with * [Eiger] Options: FULL_SPEED (Default), HALF_SPEED, QUARTER_SPEED \n
* setting number of interfaces to 2. \n Also overwrites adcphase to * [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. * 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<defs::speedLevel> getReadoutSpeedList() const;
/** [Jungfrau][CTB][Moench] */ /** [Jungfrau][CTB][Moench] */
Result<int> getADCPhase(Positions pos = {}) const; Result<int> getADCPhase(Positions pos = {}) const;

View File

@ -605,32 +605,33 @@ std::string CmdProxy::Exptime(int action) {
return os.str(); return os.str();
} }
std::string CmdProxy::Speed(int action) { std::string CmdProxy::ReadoutSpeed(int action) {
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { if (action == defs::HELP_ACTION) {
os << "[0 or full_speed|1 or half_speed|2 or " os << "\n\t[0 or full_speed|1 or half_speed|2 or "
"quarter_speed]\n\t[Eiger][Jungfrau] Readout speed of " "quarter_speed]\n\t\t[Eiger][Jungfrau] Readout "
"chip.\n\t[Jungfrau] FULL_SPEED option only available from v2.0 " "speed of chip.\n\t\t[Eiger] Default speed is full_speed."
"boards and with setting number of interfaces to 2. Also " "\n\t\t[Jungfrau] Default speed is half_speed. full_speed "
"overwrites adcphase to recommended default. " "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'; << '\n';
} else { } else {
defs::detectorType type = det->getDetectorType().squash(); defs::detectorType type = det->getDetectorType().squash();
if (type == defs::CHIPTESTBOARD || type == defs::MOENCH) { if (type == defs::CHIPTESTBOARD || type == defs::MOENCH) {
throw sls::RuntimeError( 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( throw sls::RuntimeError(
"Speed not implemented."); // setspped one function problem. tbr "ReadoutSpeed not implemented.");
// after change
} }
if (action == defs::GET_ACTION) { if (action == defs::GET_ACTION) {
if (!args.empty()) { if (!args.empty()) {
WrongNumberOfParameters(0); WrongNumberOfParameters(0);
} }
auto t = det->getSpeed(std::vector<int>{det_id}); auto t = det->getReadoutSpeed(std::vector<int>{det_id});
os << OutString(t) << '\n'; os << OutString(t) << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (args.size() != 1) { if (args.size() != 1) {
@ -655,7 +656,7 @@ std::string CmdProxy::Speed(int action) {
} catch (...) { } catch (...) {
t = sls::StringTo<defs::speedLevel>(args[0]); t = sls::StringTo<defs::speedLevel>(args[0]);
} }
det->setSpeed(t, std::vector<int>{det_id}); det->setReadoutSpeed(t, std::vector<int>{det_id});
os << sls::ToString(t) << '\n'; // no args to convert 0,1,2 as well os << sls::ToString(t) << '\n'; // no args to convert 0,1,2 as well
} else { } else {
throw sls::RuntimeError("Unknown action"); throw sls::RuntimeError("Unknown action");

View File

@ -591,7 +591,8 @@ class CmdProxy {
/* acquisition parameters */ /* acquisition parameters */
{"cycles", "triggers"}, {"cycles", "triggers"},
{"cyclesl", "triggersl"}, {"cyclesl", "triggersl"},
{"clkdivider", "speed"}, {"clkdivider", "readoutspeed"},
{"speed", "readoutspeed"},
{"vhighvoltage", "highvoltage"}, {"vhighvoltage", "highvoltage"},
{"digitest", "imagetest"}, {"digitest", "imagetest"},
{"filter", "filterresistor"}, {"filter", "filterresistor"},
@ -792,7 +793,7 @@ class CmdProxy {
{"drlist", &CmdProxy::drlist}, {"drlist", &CmdProxy::drlist},
{"timing", &CmdProxy::timing}, {"timing", &CmdProxy::timing},
{"timinglist", &CmdProxy::timinglist}, {"timinglist", &CmdProxy::timinglist},
{"speed", &CmdProxy::Speed}, {"speed", &CmdProxy::ReadoutSpeed},
{"adcphase", &CmdProxy::Adcphase}, {"adcphase", &CmdProxy::Adcphase},
{"maxadcphaseshift", &CmdProxy::maxadcphaseshift}, {"maxadcphaseshift", &CmdProxy::maxadcphaseshift},
{"dbitphase", &CmdProxy::Dbitphase}, {"dbitphase", &CmdProxy::Dbitphase},
@ -1097,7 +1098,7 @@ class CmdProxy {
std::string Acquire(int action); std::string Acquire(int action);
std::string Exptime(int action); std::string Exptime(int action);
std::string DynamicRange(int action); std::string DynamicRange(int action);
std::string Speed(int action); std::string ReadoutSpeed(int action);
std::string Adcphase(int action); std::string Adcphase(int action);
std::string Dbitphase(int action); std::string Dbitphase(int action);
std::string ClockFrequency(int action); std::string ClockFrequency(int action);

View File

@ -412,20 +412,31 @@ std::vector<defs::timingMode> Detector::getTimingModeList() const {
} }
} }
Result<defs::speedLevel> Detector::getSpeed(Positions pos) const { Result<defs::speedLevel> Detector::getReadoutSpeed(Positions pos) const {
auto res = pimpl->Parallel(&Module::getClockDivider, pos, defs::RUN_CLOCK); return pimpl->Parallel(&Module::getReadoutSpeed, pos);
Result<defs::speedLevel> speedResult(res.size());
for (unsigned int i = 0; i < res.size(); ++i) {
speedResult[i] = static_cast<defs::speedLevel>(res[i]);
}
return speedResult;
} }
void Detector::setSpeed(defs::speedLevel value, Positions pos) { void Detector::setReadoutSpeed(defs::speedLevel value, Positions pos) {
pimpl->Parallel(&Module::setClockDivider, pos, defs::RUN_CLOCK, pimpl->Parallel(&Module::getReadoutSpeed, pos, value);
static_cast<int>(value));
} }
std::vector<defs::speedLevel> Detector::getReadoutSpeedList() const {
switch (getDetectorType().squash()) {
case defs::EIGER:
case defs::JUNGFRAU:
return std::vector<defs::speedLevel>{defs::FULL_SPEED,
defs::HALF_SPEED,
defs::QUARTER_SPEED};
case defs::GOTTHARD2:
return std::vector<defs::speedLevel>{defs::G_108MHZ,
defs::G_144MHZ};
default:
throw RuntimeError("Readout speed not implemented for this detector");
}
}
Result<int> Detector::getADCPhase(Positions pos) const { Result<int> Detector::getADCPhase(Positions pos) const {
return pimpl->Parallel(&Module::getClockPhase, pos, defs::ADC_CLOCK, false); return pimpl->Parallel(&Module::getClockPhase, pos, defs::ADC_CLOCK, false);
} }

View File

@ -600,6 +600,14 @@ void Module::setTimingMode(timingMode value) {
} }
} }
slsDetectorDefs::speedLevel Module::getReadoutSpeed() const {
return sendToDetector<speedLevel>(F_GET_READOUT_SPEED);
}
void Module::setReadoutSpeed(speedLevel value) {
sendToDetector<int>(F_SET_READOUT_SPEED, value);
}
int Module::getClockDivider(int clkIndex) const { int Module::getClockDivider(int clkIndex) const {
return sendToDetector<int>(F_GET_CLOCK_DIVIDER, clkIndex); return sendToDetector<int>(F_GET_CLOCK_DIVIDER, clkIndex);
} }

View File

@ -144,6 +144,8 @@ class Module : public virtual slsDetectorDefs {
void setDynamicRange(int dr); void setDynamicRange(int dr);
timingMode getTimingMode() const; timingMode getTimingMode() const;
void setTimingMode(timingMode value); void setTimingMode(timingMode value);
speedLevel getReadoutSpeed() const;
void setReadoutSpeed(speedLevel value);
int getClockDivider(int clkIndex) const; int getClockDivider(int clkIndex) const;
void setClockDivider(int clkIndex, int value); void setClockDivider(int clkIndex, int value);
int getClockPhase(int clkIndex, bool inDegrees) const; int getClockPhase(int clkIndex, bool inDegrees) const;

View File

@ -889,54 +889,84 @@ TEST_CASE("timinglist", "[.cmd]") {
REQUIRE_THROWS(proxy.Call("timinglist", {}, -1, PUT)); REQUIRE_THROWS(proxy.Call("timinglist", {}, -1, PUT));
} }
TEST_CASE("speed", "[.cmd]") { TEST_CASE("readoutspeed", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash(); auto det_type = det.getDetectorType().squash();
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("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");
}
if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) { if (det_type == defs::EIGER || det_type == defs::JUNGFRAU) {
auto prev_val = det.getSpeed();
// full speed for jungfrau only works for new boards
/*
{ {
std::ostringstream oss1, oss2, oss3, oss4; std::ostringstream oss1, oss2, oss3, oss4;
proxy.Call("speed", {"0"}, -1, PUT, oss1); proxy.Call("readoutspeed", {"1"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "speed full_speed\n"); REQUIRE(oss1.str() == "readoutspeed half_speed\n");
proxy.Call("speed", {}, -1, GET, oss2); proxy.Call("readoutspeed", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "speed full_speed\n"); REQUIRE(oss2.str() == "readoutspeed half_speed\n");
proxy.Call("speed", {"full_speed"}, -1, PUT, oss3); proxy.Call("readoutspeed", {"half_speed"}, -1, PUT, oss3);
REQUIRE(oss3.str() == "speed full_speed\n"); REQUIRE(oss3.str() == "readoutspeed half_speed\n");
proxy.Call("speed", {}, -1, GET, oss4); proxy.Call("readoutspeed", {}, -1, GET, oss4);
REQUIRE(oss4.str() == "speed full_speed\n"); REQUIRE(oss4.str() == "readoutspeed half_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");
} }
{ {
std::ostringstream oss1, oss2, oss3, oss4; std::ostringstream oss1, oss2, oss3, oss4;
proxy.Call("speed", {"2"}, -1, PUT, oss1); proxy.Call("readoutspeed", {"2"}, -1, PUT, oss1);
REQUIRE(oss1.str() == "speed quarter_speed\n"); REQUIRE(oss1.str() == "readoutspeed quarter_speed\n");
proxy.Call("speed", {}, -1, GET, oss2); proxy.Call("readoutspeed", {}, -1, GET, oss2);
REQUIRE(oss2.str() == "speed quarter_speed\n"); REQUIRE(oss2.str() == "readoutspeed quarter_speed\n");
proxy.Call("speed", {"quarter_speed"}, -1, PUT, oss3); proxy.Call("readoutspeed", {"quarter_speed"}, -1, PUT, oss3);
REQUIRE(oss3.str() == "speed quarter_speed\n"); REQUIRE(oss3.str() == "readoutspeed quarter_speed\n");
proxy.Call("speed", {}, -1, GET, oss4); proxy.Call("readoutspeed", {}, -1, GET, oss4);
REQUIRE(oss4.str() == "speed quarter_speed\n"); REQUIRE(oss4.str() == "readoutspeed quarter_speed\n");
} }
REQUIRE_THROWS(proxy.Call("readoutspeed", {"108"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("readoutspeed", {"144"}, -1, PUT));
}
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) { for (int i = 0; i != det.size(); ++i) {
det.setSpeed(prev_val[i], {i}); det.setReadoutSpeed(prev_val[i], {i});
} }
} else { } else {
REQUIRE_THROWS(proxy.Call("speed", {"0"}, -1, PUT)); REQUIRE_THROWS(proxy.Call("readoutspeed", {"0"}, -1, PUT));
REQUIRE_THROWS(proxy.Call("speed", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("readoutspeed", {}, -1, GET));
} }
} }

View File

@ -377,7 +377,7 @@ typedef struct {
enum readoutMode { ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL }; enum readoutMode { ANALOG_ONLY, DIGITAL_ONLY, ANALOG_AND_DIGITAL };
/** chip speed */ /** 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 * burst mode for gotthard2

View File

@ -249,6 +249,8 @@ enum detFuncs {
F_CLEAR_ALL_UDP_DEST, F_CLEAR_ALL_UDP_DEST,
F_GET_UDP_FIRST_DEST, F_GET_UDP_FIRST_DEST,
F_SET_UDP_FIRST_DEST, F_SET_UDP_FIRST_DEST,
F_GET_READOUT_SPEED,
F_SET_READOUT_SPEED,
NUM_DET_FUNCTIONS, NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this 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_CLEAR_ALL_UDP_DEST: return "F_CLEAR_ALL_UDP_DEST";
case F_GET_UDP_FIRST_DEST: return "F_GET_UDP_FIRST_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_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 NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS";
case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";

View File

@ -247,6 +247,10 @@ std::string ToString(const defs::speedLevel s) {
return std::string("half_speed"); return std::string("half_speed");
case defs::QUARTER_SPEED: case defs::QUARTER_SPEED:
return std::string("quarter_speed"); return std::string("quarter_speed");
case defs::G_108MHZ:
return std::string("108");
case defs::G_144MHZ:
return std::string("144");
default: default:
return std::string("Unknown"); return std::string("Unknown");
} }
@ -707,6 +711,10 @@ template <> defs::speedLevel StringTo(const std::string &s) {
return defs::HALF_SPEED; return defs::HALF_SPEED;
if (s == "quarter_speed") if (s == "quarter_speed")
return defs::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); throw sls::RuntimeError("Unknown speed " + s);
} }