diff --git a/python/scripts/test_virtual.py b/python/scripts/test_virtual.py index 77bb66762..f5dc302cd 100644 --- a/python/scripts/test_virtual.py +++ b/python/scripts/test_virtual.py @@ -156,4 +156,28 @@ def test_period(virtual_jf_detectors): d.period = t assert d.period == 10e-6 - \ No newline at end of file +def test_gainmode(virtual_jf_detectors): + d = ExperimentalDetector() + assert d.gainMode == gainMode.NORMAL_GAIN_MODE + + gain_list = [ + gainMode.NORMAL_GAIN_MODE, + gainMode.FORCE_SWITCH_G1, + gainMode.FORCE_SWITCH_G2, + ] + + # Set all viable gain for Jungfrau to make sure nothing is crashing + for gain in gain_list: + d.gainMode = gain + assert d.gainMode == gain + + d.setGainMode(gainMode.FORCE_SWITCH_G1, [1]) + assert d.gainMode == [ + gainMode.NORMAL_GAIN_MODE, + gainMode.FORCE_SWITCH_G1, + gainMode.FORCE_SWITCH_G2, + ] + + d.gainMode = gainMode.FORCE_SWITCH_G1 + assert d.gainMode == gainMode.FORCE_SWITCH_G1 + diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index 82df910b0..819522a56 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -2165,6 +2165,26 @@ class Detector(CppDetectorApi): def selinterface(self, i): ut.set_using_dict(self.selectUDPInterface, i) + @property + def gainmodelist(self): + """List of gainmode implemented for this detector.""" + return self.getGainModeList() + + @property + def gainmode(self): + """ + [Jungfrau] Detector gain mode. Enum: gainMode + Note + ----- + + [Jungfrau] NORMAL_GAIN_MODE, FORCE_SWITCH_G1, FORCE_SWITCH_G2 + """ + return element_if_equal(self.getGainMode()) + + @gainmode.setter + def gainmode(self, value): + self.setGainMode(value) + """ ---------------------------<<>>--------------------------- """ diff --git a/python/slsdet/enums.py b/python/slsdet/enums.py index 48c2d51b3..fdbfe7d2f 100644 --- a/python/slsdet/enums.py +++ b/python/slsdet/enums.py @@ -1,17 +1,20 @@ +""" +Automatically improt all enums from slsDetectorDefs and give an +alias with their name in the enum module. All names from the enum +module is later imported into slsdet + +Example: detectorType = _slsdet.slsDetectorDefs.detectorType +Usage can later be: + +from slsdet import detectorType +if dt === detectorType.EIGER: + #do something + +""" + import _slsdet -runStatus = _slsdet.slsDetectorDefs.runStatus -speedLevel = _slsdet.slsDetectorDefs.speedLevel -detectorType = _slsdet.slsDetectorDefs.detectorType -frameDiscardPolicy = _slsdet.slsDetectorDefs.frameDiscardPolicy -fileFormat = _slsdet.slsDetectorDefs.fileFormat -dimension = _slsdet.slsDetectorDefs.dimension -externalSignalFlag = _slsdet.slsDetectorDefs.externalSignalFlag -timingMode = _slsdet.slsDetectorDefs.timingMode -dacIndex = _slsdet.slsDetectorDefs.dacIndex -detectorSettings = _slsdet.slsDetectorDefs.detectorSettings -clockIndex = _slsdet.slsDetectorDefs.clockIndex -readoutMode = _slsdet.slsDetectorDefs.readoutMode -burstMode = _slsdet.slsDetectorDefs.burstMode -timingSourceType = _slsdet.slsDetectorDefs.timingSourceType -M3_GainCaps = _slsdet.slsDetectorDefs.M3_GainCaps \ No newline at end of file +for name, cls in _slsdet.slsDetectorDefs.__dict__.items(): + if isinstance(cls, type): + exec(f'{name} = {cls.__module__}.{cls.__qualname__}') + diff --git a/python/src/detector.cpp b/python/src/detector.cpp index e265814c7..4b3200ce0 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1002,6 +1002,17 @@ void init_det(py::module &m) { (void (Detector::*)(sls::ns, sls::Positions)) & Detector::setStorageCellDelay, py::arg(), py::arg() = Positions{}) + .def("getGainModeList", + (std::vector(Detector::*)() const) & + Detector::getGainModeList) + .def("getGainMode", + (Result(Detector::*)(sls::Positions) const) & + Detector::getGainMode, + py::arg() = Positions{}) + .def("setGainMode", + (void (Detector::*)(defs::gainMode, sls::Positions)) & + Detector::setGainMode, + py::arg(), py::arg() = Positions{}) .def("getROI", (Result(Detector::*)(sls::Positions) const) & Detector::getROI, diff --git a/python/src/enums.cpp b/python/src/enums.cpp index a04054672..851779b13 100644 --- a/python/src/enums.cpp +++ b/python/src/enums.cpp @@ -305,4 +305,10 @@ void init_enums(py::module &m) { .value("DEFAULT_ALGORITHM", slsDetectorDefs::vetoAlgorithm::DEFAULT_ALGORITHM) .export_values(); + + py::enum_(Defs, "gainMode") + .value("NORMAL_GAIN_MODE", slsDetectorDefs::gainMode::NORMAL_GAIN_MODE) + .value("FORCE_SWITCH_G1", slsDetectorDefs::gainMode::FORCE_SWITCH_G1) + .value("FORCE_SWITCH_G2", slsDetectorDefs::gainMode::FORCE_SWITCH_G2) + .export_values(); } diff --git a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h index 55e3a1419..2eff513e6 100644 --- a/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h +++ b/slsDetectorServers/jungfrauDetectorServer/RegisterDefs.h @@ -98,6 +98,21 @@ #define TEMPERATURE_POLARITY_BIT (11) #define TEMPERATURE_POLARITY_MSK (0x00000001 << TEMPERATURE_POLARITY_BIT) +/* Config Status Register for chip 1.1 */ +#define CONFIG_V11_STATUS_REG (0x1D << MEM_MAP_SHIFT) + +#define CONFIG_V11_STATUS_FLTR_CLL_OFST (0) +#define CONFIG_V11_STATUS_FLTR_CLL_MSK (0x00000FFF << CONFIG_V11_STATUS_FLTR_CLL_OFST) +#define CONFIG_V11_STATUS_STRG_CLL_OFST (12) +#define CONFIG_V11_STATUS_STRG_CLL_MSK (0x0000000F << CONFIG_V11_STATUS_STRG_CLL_OFST) +// CSM mode = high current (100%), low current (16%) +#define CONFIG_V11_STATUS_CRRNT_SRC_MODE_OFST (19) +#define CONFIG_V11_STATUS_CRRNT_SRC_MODE_MSK (0x00000001 << CONFIG_V11_STATUS_CRRNT_SRC_MODE_OFST) +#define CONFIG_V11_STATUS_FLTR_RSSTR_OFST (21) +#define CONFIG_V11_STATUS_FLTR_RSSTR_MSK (0x00000001 << CONFIG_V11_STATUS_FLTR_RSSTR_OFST) +#define CONFIG_V11_STATUS_AUTO_MODE_OVRRD_OFST (23) +#define CONFIG_V11_STATUS_AUTO_MODE_OVRRD_MSK (0x00000001 << CONFIG_V11_STATUS_AUTO_MODE_OVRRD_OFST) + /* Get Frames from Start 64 bit register (frames from last reset using * CONTROL_CRST) */ #define FRAMES_FROM_START_LSB_REG (0x22 << MEM_MAP_SHIFT) @@ -159,8 +174,10 @@ // (RDT + 1) * 25ns #define CONFIG_RDT_TMR_OFST (0) #define CONFIG_RDT_TMR_MSK (0x0000FFFF << CONFIG_RDT_TMR_OFST) +// if 0, outer is the primary interface +// bottom via port 0 (outer) #define CONFIG_OPRTN_MDE_2_X_10GbE_OFST (16) -#define CONFIG_OPRTN_MDE_2_X_10GbE_MSK (0x00000001 << CONFIG_OPRTN_MDE_2_X_10GbE_OFST) // if 0, outer is the primary interface +#define CONFIG_OPRTN_MDE_2_X_10GbE_MSK (0x00000001 << CONFIG_OPRTN_MDE_2_X_10GbE_OFST) #define CONFIG_INNR_PRIMRY_INTRFCE_OFST (17) #define CONFIG_INNR_PRIMRY_INTRFCE_MSK (0x00000001 << CONFIG_INNR_PRIMRY_INTRFCE_OFST) #define CONFIG_READOUT_SPEED_OFST (20) @@ -172,6 +189,8 @@ #define CONFIG_TDMA_ENABLE_MSK (0x00000001 << CONFIG_TDMA_ENABLE_OFST) #define CONFIG_TDMA_TIMESLOT_OFST (25) // 1ms #define CONFIG_TDMA_TIMESLOT_MSK (0x0000001F << CONFIG_TDMA_TIMESLOT_OFST) +#define CONFIG_BOTTOM_INVERT_STREAM_OFST (30) +#define CONFIG_BOTTOM_INVERT_STREAM_MSK (0x0000001F << CONFIG_BOTTOM_INVERT_STREAM_OFST) #define CONFIG_ETHRNT_FLW_CNTRL_OFST (31) #define CONFIG_ETHRNT_FLW_CNTRL_MSK (0x00000001 << CONFIG_ETHRNT_FLW_CNTRL_OFST) @@ -234,8 +253,6 @@ #define CONFIG_V11_FLTR_RSSTR_MSK (0x00000001 << CONFIG_V11_FLTR_RSSTR_OFST) #define CONFIG_V11_AUTO_MODE_OVRRD_OFST (23) #define CONFIG_V11_AUTO_MODE_OVRRD_MSK (0x00000001 << CONFIG_V11_AUTO_MODE_OVRRD_OFST) -#define CONFIG_V11_WR_CHIP_CNFG_OFST (31) -#define CONFIG_V11_WR_CHIP_CNFG_MSK (0x00000001 << CONFIG_V11_WR_CHIP_CNFG_OFST) /* Sample Register */ #define SAMPLE_REG (0x59 << MEM_MAP_SHIFT) @@ -308,11 +325,9 @@ /** DAQ Register */ #define DAQ_REG (0x5D << MEM_MAP_SHIFT) -#define DAQ_SETTINGS_MSK (DAQ_HIGH_GAIN_MSK | DAQ_FIX_GAIN_MSK | DAQ_FRCE_SWTCH_GAIN_MSK) +// dynamic gain (default) #define DAQ_HIGH_GAIN_OFST (0) #define DAQ_HIGH_GAIN_MSK (0x00000001 << DAQ_HIGH_GAIN_OFST) -#define DAQ_FIX_GAIN_DYNMC_VAL ((0x0 << DAQ_HIGH_GAIN_OFST) & DAQ_HIGH_GAIN_MSK) -#define DAQ_FIX_GAIN_HIGHGAIN_VAL ((0x1 << DAQ_HIGH_GAIN_OFST) & DAQ_HIGH_GAIN_MSK) #define DAQ_FIX_GAIN_OFST (1) #define DAQ_FIX_GAIN_MSK (0x00000003 << DAQ_FIX_GAIN_OFST) #define DAQ_FIX_GAIN_STG_1_VAL ((0x1 << DAQ_FIX_GAIN_OFST) & DAQ_FIX_GAIN_MSK) @@ -323,6 +338,7 @@ #define DAQ_STRG_CELL_SLCT_MSK (0x0000000F << DAQ_STRG_CELL_SLCT_OFST) #define DAQ_FRCE_SWTCH_GAIN_OFST (12) #define DAQ_FRCE_SWTCH_GAIN_MSK (0x00000003 << DAQ_FRCE_SWTCH_GAIN_OFST) +#define DAQ_FRCE_GAIN_STG_0_VAL ((0x0 << DAQ_FRCE_SWTCH_GAIN_OFST) & DAQ_FRCE_SWTCH_GAIN_MSK) #define DAQ_FRCE_GAIN_STG_1_VAL ((0x1 << DAQ_FRCE_SWTCH_GAIN_OFST) & DAQ_FRCE_SWTCH_GAIN_MSK) #define DAQ_FRCE_GAIN_STG_2_VAL ((0x3 << DAQ_FRCE_SWTCH_GAIN_OFST) & DAQ_FRCE_SWTCH_GAIN_MSK) #define DAQ_ELCTRN_CLLCTN_MDE_OFST (14) @@ -379,6 +395,11 @@ #define FRAME_NUMBER_LSB_REG (0x6A << MEM_MAP_SHIFT) #define FRAME_NUMBER_MSB_REG (0x6B << MEM_MAP_SHIFT) +/* Comparator disable time (chipv1.1) 32 bit register tT = T x 25 ns +Time before end of exposure when comparator is disabled */ +#define COMP_DSBLE_TIME_REG (0x6C << MEM_MAP_SHIFT) + + /* Trigger Delay 32 bit register */ #define SET_TRIGGER_DELAY_LSB_REG (0x70 << MEM_MAP_SHIFT) #define SET_TRIGGER_DELAY_MSB_REG (0x71 << MEM_MAP_SHIFT) diff --git a/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer b/slsDetectorServers/jungfrauDetectorServer/bin/jungfrauDetectorServer_developer index 12d73a801..8a664f42e 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 bf2c6c031..6c92644f8 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorFunctionList.c @@ -794,6 +794,16 @@ int selectStoragecellStart(int pos) { bus_w(addr, bus_r(addr) & ~mask); bus_w(addr, bus_r(addr) | ((value << offset) & mask)); } + + // read value back + // chipv1.1, writing and reading registers are different +#ifndef VIRTUAL + if (getChipVersion() == 11) { + addr = CONFIG_V11_STATUS_REG; + mask = CONFIG_V11_STATUS_STRG_CLL_MSK; + offset = CONFIG_V11_STATUS_STRG_CLL_OFST; + } +#endif int retval = ((bus_r(addr) & mask) >> offset); if (getChipVersion() == 11) { // get which bit @@ -1036,21 +1046,19 @@ enum detectorSettings setSettings(enum detectorSettings sett) { // set settings switch (sett) { case DYNAMICGAIN: - bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); + bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_HIGH_GAIN_MSK); LOG(logINFO, - ("Set settings - Dyanmic Gain, DAQ Reg: 0x%x\n", bus_r(DAQ_REG))); + ("Set settings - Dyanmic Gain [DAQ Reg:0x%x]\n", bus_r(DAQ_REG))); dacVals = defaultDacValue_G0; break; case DYNAMICHG0: - bus_w(DAQ_REG, bus_r(DAQ_REG) & ~DAQ_SETTINGS_MSK); - bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_FIX_GAIN_HIGHGAIN_VAL); - LOG(logINFO, ("Set settings - Dyanmic High Gain 0, DAQ Reg: 0x%x\n", + bus_w(DAQ_REG, bus_r(DAQ_REG) | DAQ_HIGH_GAIN_MSK); + LOG(logINFO, ("Set settings - Dyanmic High Gain 0 [DAQ Reg:0x%x]\n", bus_r(DAQ_REG))); dacVals = defaultDacValue_HG0; break; default: - LOG(logERROR, - ("This settings is not defined for this detector %d\n", (int)sett)); + LOG(logERROR, ("This settings %d is not defined\n", (int)sett)); return -1; } @@ -1107,6 +1115,53 @@ void validateSettings() { enum detectorSettings getSettings() { return thisSettings; } +enum gainMode getGainMode() { + uint32_t retval = bus_r(DAQ_REG) & DAQ_FRCE_SWTCH_GAIN_MSK; + + switch (retval) { + case DAQ_FRCE_GAIN_STG_0_VAL: + return NORMAL_GAIN_MODE; + case DAQ_FRCE_GAIN_STG_1_VAL: + return FORCE_SWITCH_G1; + case DAQ_FRCE_GAIN_STG_2_VAL: + return FORCE_SWITCH_G2; + default: + LOG(logERROR, ("This gain mode %d is not defined [DAQ reg: %d]\n", + (retval << DAQ_FRCE_SWTCH_GAIN_OFST), retval)); + return -1; + } +} + +void setGainMode(enum gainMode mode) { + uint32_t addr = DAQ_REG; + uint32_t value = bus_r(addr); + + switch (mode) { + case NORMAL_GAIN_MODE: + value &= ~(DAQ_FRCE_SWTCH_GAIN_MSK); + bus_w(addr, value); + LOG(logINFO, ("Set gain mode - Normal Gain Mode [DAQ Reg:0x%x]\n", + bus_r(DAQ_REG))); + break; + case FORCE_SWITCH_G1: + value &= ~(DAQ_FRCE_SWTCH_GAIN_MSK); + value |= DAQ_FRCE_GAIN_STG_1_VAL; + bus_w(addr, value); + LOG(logINFO, ("Set gain mode - Force Switch G1 [DAQ Reg:0x%x]\n", + bus_r(DAQ_REG))); + break; + case FORCE_SWITCH_G2: + value &= ~(DAQ_FRCE_SWTCH_GAIN_MSK); + value |= DAQ_FRCE_GAIN_STG_2_VAL; + bus_w(addr, value); + LOG(logINFO, ("Set gain mode - Force Switch G2 [DAQ Reg:0x%x]\n", + bus_r(DAQ_REG))); + break; + default: + LOG(logERROR, ("This gain mode %d is not defined\n", (int)mode)); + } +} + /* parameters - dac, adc, hv */ void setDAC(enum DACINDEX ind, int val, int mV) { if (val < 0) @@ -1582,7 +1637,9 @@ void configureChip() { // only for chipv1.1 if (chipVersion == 11) { LOG(logINFOBLUE, ("Configuring chip\n")); - bus_w(CONFIG_V11_REG, bus_r(CONFIG_V11_REG) & CONFIG_V11_WR_CHIP_CNFG_MSK); + // write same register values back to configure chip + uint32_t val = bus_r(CONFIG_V11_REG); + bus_w(CONFIG_V11_REG, val); chipConfigured = 1; } } diff --git a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h index 0c74880ce..9182ef65d 100644 --- a/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/jungfrauDetectorServer/slsDetectorServer_defs.h @@ -65,7 +65,7 @@ enum DACINDEX { #define NUMSETTINGS (2) #define NSPECIALDACS (3) -#define SPECIALDACINDEX {J_VB_COMP, J_VREF_DS, J_VREF_COMP}; +#define SPECIALDACINDEX {J_VREF_PRECH, J_VREF_DS, J_VREF_COMP}; #define SPECIAL_DEFAULT_DYNAMIC_GAIN_VALS \ { 1000, 500, 400 } #define SPECIAL_DEFAULT_DYNAMICHG0_GAIN_VALS \ diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index e86f8907a..b971e56ad 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -301,6 +301,10 @@ enum detectorSettings setSettings(enum detectorSettings sett); void validateSettings(); #endif enum detectorSettings getSettings(); +#ifdef JUNGFRAUD +enum gainMode getGainMode(); +void setGainMode(enum gainMode mode); +#endif // parameters - threshold #ifdef EIGERD diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index 9313284af..d1f0aa6e6 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -257,3 +257,5 @@ int set_veto_algorithm(int); int get_chip_version(int); int get_default_dac(int); int set_default_dac(int); +int get_gain_mode(int); +int set_gain_mode(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 443ec30eb..35668d4c9 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -382,6 +382,8 @@ void function_table() { flist[F_GET_CHIP_VERSION] = &get_chip_version; flist[F_GET_DEFAULT_DAC] = &get_default_dac; flist[F_SET_DEFAULT_DAC] = &set_default_dac; + flist[F_GET_GAIN_MODE] = &get_gain_mode; + flist[F_SET_GAIN_MODE] = &set_gain_mode; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -8551,4 +8553,63 @@ int set_default_dac(int file_des) { } #endif return Server_SendResult(file_des, INT32, NULL, 0); -} \ No newline at end of file +} + +int get_gain_mode(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + enum gainMode retval = NORMAL_GAIN_MODE; + LOG(logDEBUG1, ("Getting gain mode\n")); + +#ifndef JUNGFRAUD + functionNotImplemented(); +#else + // get only + retval = getGainMode(); + LOG(logDEBUG1, ("gainmode retval: %u\n", retval)); + if ((int)retval == -1) { + ret = FAIL; + strcpy(mess, "Could not get gain mode.\n"); + LOG(logERROR, (mess)); + } +#endif + return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); +} + +int set_gain_mode(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + enum gainMode gainmode = arg; + LOG(logINFO, ("Setting gain mode %d\n", (int)gainmode)); + +#ifndef JUNGFRAUD + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + switch (gainmode) { + case NORMAL_GAIN_MODE: + case FORCE_SWITCH_G1: + case FORCE_SWITCH_G2: + break; + default: + modeNotImplemented("Gain Mode Index", (int)gainmode); + break; + } + + setGainMode(gainmode); + int retval = getGainMode(); + LOG(logDEBUG1, ("gainmode retval: %u\n", retval)); + if (retval == -1) { + ret = FAIL; + strcpy(mess, "Could not get gain mode.\n"); + LOG(logERROR, (mess)); + } + validate(&ret, mess, arg, retval, "set gain mode", DEC); + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 024e41893..dc4f6c6ba 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1164,6 +1164,17 @@ class Detector { * Only applicable for chipv1.0. */ void setStorageCellDelay(ns value, Positions pos = {}); + + /** list of possible gainmode */ + std::vector getGainModeList() const; + + /** [Jungfrau]*/ + Result getGainMode(Positions pos = {}) const; + + /** [Jungfrau] Options: NORMAL_GAIN_MODE, FORCE_SWITCH_G1, FORCE_SWITCH_G2\n + */ + void setGainMode(const defs::gainMode mode, Positions pos = {}); + ///@{ /** @name Gotthard Specific */ diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 87eb12bab..9ada9ea09 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -929,6 +929,7 @@ class CmdProxy { {"storagecells", &CmdProxy::storagecells}, {"storagecell_start", &CmdProxy::storagecell_start}, {"storagecell_delay", &CmdProxy::storagecell_delay}, + {"gainmode", &CmdProxy::gainmode}, /* Gotthard Specific */ {"roi", &CmdProxy::ROI}, @@ -1864,6 +1865,11 @@ class CmdProxy { "Additional time delay between 2 consecutive exposures in burst mode " "(resolution of 25ns). Only applicable for chipv1.0. For advanced users only."); + INTEGER_COMMAND_VEC_ID( + gainmode, getGainMode, setGainMode, + sls::StringTo, + "[forceswitchg1, forceswitchg2]\n\t[Jungfrau] Gain mode."); + /* Gotthard Specific */ TIME_GET_COMMAND(exptimel, getExptimeLeft, "[(optional unit) ns|us|ms|s]\n\t[Gotthard] Exposure time " diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 7b397efa7..ea889fff2 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1483,6 +1483,26 @@ void Detector::setStorageCellDelay(ns value, Positions pos) { pimpl->Parallel(&Module::setStorageCellDelay, pos, value.count()); } +std::vector Detector::getGainModeList() const { + switch (getDetectorType().squash()) { + case defs::JUNGFRAU: + return std::vector{defs::NORMAL_GAIN_MODE, + defs::FORCE_SWITCH_G1, + defs::FORCE_SWITCH_G2}; + break; + default: + throw RuntimeError("Gain mode is not implemented for this detector."); + } +} + +Result Detector::getGainMode(Positions pos) const { + return pimpl->Parallel(&Module::getGainMode, pos); +} + +void Detector::setGainMode(const defs::gainMode mode, Positions pos) { + pimpl->Parallel(&Module::setGainMode, pos, mode); +} + // Gotthard Specific Result Detector::getROI(Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index bb46d9ee2..ac9ecc212 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1601,6 +1601,14 @@ void Module::setStorageCellDelay(int64_t value) { sendToDetector(F_SET_STORAGE_CELL_DELAY, value, nullptr); } +slsDetectorDefs::gainMode Module::getGainMode() const { + return sendToDetector(F_GET_GAIN_MODE); +} + +void Module::setGainMode(const slsDetectorDefs::gainMode mode) { + sendToDetector(F_SET_GAIN_MODE, mode, nullptr); +} + // Gotthard Specific slsDetectorDefs::ROI Module::getROI() const { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 2e7248120..d7f75fef3 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -369,6 +369,8 @@ class Module : public virtual slsDetectorDefs { void setStorageCellStart(int pos); int64_t getStorageCellDelay() const; void setStorageCellDelay(int64_t value); + gainMode getGainMode() const; + void setGainMode(const gainMode mode); /************************************************** * * diff --git a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp index 154a67d12..f894e4105 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp @@ -408,4 +408,38 @@ TEST_CASE("storagecell_delay", "[.cmd]") { REQUIRE_THROWS(proxy.Call("storagecell_delay", {}, -1, GET)); REQUIRE_THROWS(proxy.Call("storagecell_delay", {"0"}, -1, PUT)); } -} \ No newline at end of file +} + +TEST_CASE("gainmode", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU) { + auto prev_val = det.getGainMode(); + { + std::ostringstream oss; + proxy.Call("gainmode", {"forceswitchg1"}, -1, PUT, oss); + REQUIRE(oss.str() == "gainmode forceswitchg1\n"); + } + { + std::ostringstream oss; + proxy.Call("gainmode", {}, -1, GET, oss); + REQUIRE(oss.str() == "gainmode forceswitchg1\n"); + } + { + std::ostringstream oss; + proxy.Call("gainmode", {"forceswitchg2"}, -1, PUT, oss); + REQUIRE(oss.str() == "gainmode forceswitchg2\n"); + } + { + std::ostringstream oss; + proxy.Call("gainmode", {"normal"}, -1, PUT, oss); + REQUIRE(oss.str() == "gainmode normal\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setGainMode(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("gainmode", {}, -1, GET)); + } +} diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index a5b71c716..f10760621 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -40,6 +40,7 @@ std::string ToString(const defs::M3_GainCaps s); std::string ToString(const defs::portPosition s); std::string ToString(const defs::ethernetInterface s); std::string ToString(const defs::vetoAlgorithm s); +std::string ToString(const defs::gainMode s); std::string ToString(const slsDetectorDefs::xy &coord); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord); @@ -305,6 +306,7 @@ template <> defs::M3_GainCaps StringTo(const std::string &s); template <> defs::portPosition StringTo(const std::string &s); template <> defs::ethernetInterface StringTo(const std::string &s); template <> defs::vetoAlgorithm StringTo(const std::string &s); +template <> defs::gainMode 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 6f5a4996a..b4ce1bf87 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -414,6 +414,8 @@ typedef struct { enum vetoAlgorithm { DEFAULT_ALGORITHM }; + enum gainMode { NORMAL_GAIN_MODE, FORCE_SWITCH_G1, FORCE_SWITCH_G2 }; + #ifdef __cplusplus /** scan structure */ diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index db452dcf0..0a955cec0 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -233,6 +233,8 @@ enum detFuncs { F_GET_CHIP_VERSION, F_GET_DEFAULT_DAC, F_SET_DEFAULT_DAC, + F_GET_GAIN_MODE, + F_SET_GAIN_MODE, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -572,6 +574,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_CHIP_VERSION: return "F_GET_CHIP_VERSION"; case F_GET_DEFAULT_DAC: return "F_GET_DEFAULT_DAC"; case F_SET_DEFAULT_DAC: return "F_SET_DEFAULT_DAC"; + case F_GET_GAIN_MODE: return "F_GET_GAIN_MODE"; + case F_SET_GAIN_MODE: return "F_SET_GAIN_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 04d04811d..fbf82c419 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -6,7 +6,7 @@ #define APICTB 0x210729 #define APIGOTTHARD 0x210729 #define APIGOTTHARD2 0x210729 -#define APIJUNGFRAU 0x210729 #define APIMYTHEN3 0x210729 #define APIMOENCH 0x210729 #define APIEIGER 0x210729 +#define APIJUNGFRAU 0x210802 diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index fa6fdf4f6..23882768a 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -579,6 +579,19 @@ std::string ToString(const defs::vetoAlgorithm s) { } } +std::string ToString(const defs::gainMode s) { + switch (s) { + case defs::NORMAL_GAIN_MODE: + return std::string("normal"); + case defs::FORCE_SWITCH_G1: + return std::string("forceswitchg1"); + case defs::FORCE_SWITCH_G2: + return std::string("forceswitchg2"); + default: + return std::string("Unknown"); + } +} + const std::string &ToString(const std::string &s) { return s; } template <> defs::detectorType StringTo(const std::string &s) { @@ -962,6 +975,16 @@ template <> defs::vetoAlgorithm StringTo(const std::string &s) { throw sls::RuntimeError("Unknown veto algorithm " + s); } +template <> defs::gainMode StringTo(const std::string &s) { + if (s == "normal") + return defs::NORMAL_GAIN_MODE; + if (s == "forceswitchg1") + return defs::FORCE_SWITCH_G1; + if (s == "forceswitchg2") + return defs::FORCE_SWITCH_G2; + throw sls::RuntimeError("Unknown gain mode " + s); +} + template <> uint32_t StringTo(const std::string &s) { int base = s.find("0x") != std::string::npos ? 16 : 10; return std::stoul(s, nullptr, base);