From cd90f09a30caaf43a211ee78200be2cbac37e513 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 19 May 2020 18:24:32 +0200 Subject: [PATCH] WIP --- .../mythen3DetectorServer/RegisterDefs.h | 70 ++++- .../slsDetectorFunctionList.c | 280 +++++++++++++++--- .../slsDetectorServer_defs.h | 30 +- .../include/slsDetectorFunctionList.h | 14 + .../include/slsDetectorServer_funcs.h | 6 + .../src/slsDetectorServer_funcs.c | 279 ++++++++++++++++- slsDetectorSoftware/include/Detector.h | 34 ++- slsDetectorSoftware/src/CmdProxy.cpp | 188 ++++++++++++ slsDetectorSoftware/src/CmdProxy.h | 34 ++- slsDetectorSoftware/src/Detector.cpp | 37 ++- slsDetectorSoftware/src/Module.cpp | 38 ++- slsDetectorSoftware/src/Module.h | 24 +- slsSupportLib/include/sls_detector_defs.h | 7 +- slsSupportLib/include/sls_detector_funcs.h | 13 + slsSupportLib/src/ToString.cpp | 4 + 15 files changed, 966 insertions(+), 92 deletions(-) diff --git a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h index c47dfc2c9..1c1d526ae 100644 --- a/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h +++ b/slsDetectorServers/mythen3DetectorServer/RegisterDefs.h @@ -19,9 +19,6 @@ #define BASE_CONTROL (0x0000) // 0x1806_0000 - 0x1806_00FF // https://git.psi.ch/sls_detectors_firmware/mythen_III_mcb/blob/master/code/hdl/ctrl/ctrl.vhd -/* ASIC Control */ -#define BASE_ASIC (0x0100) // 0x1806_0100 - 0x1806_010F - /* ASIC Digital Interface. Data recovery core */ #define BASE_ADIF (0x0110) // 0x1806_0110 - 0x1806_011F // https://git.psi.ch/sls_detectors_firmware/vhdl_library/blob/2e81ccbdbc5cb81813ba190fbdba43e8d6884eb9/adif/adif_ctrl.vhd @@ -33,14 +30,21 @@ #define BASE_PKT (0x0130) // 0x1806_0130 - 0x1806_013F // https://git.psi.ch/sls_detectors_firmware/mythen_III_mcb/blob/master/code/hdl/pkt/pkt_ctrl.vhd -/* Pattern control and status registers */ +/* ASIC Exposure Control */ +#define BASE_ASIC_EXP (0x0180) // 0x1806_0180 - 0x1806_01BF + +/* Pattern control and status */ #define BASE_PATTERN_CONTROL (0x00200) // 0x1806_0200 - 0x1806_02FF // https://git.psi.ch/sls_detectors_firmware/vhdl_library/blob/2e81ccbdbc5cb81813ba190fbdba43e8d6884eb9/pattern_flow/pattern_flow_ctrl.vhd -/* Flow control and status registers */ +/* Flow control and status */ #define BASE_FLOW_CONTROL (0x00400) // 0x1806_0400 - 0x1806_04FF // https://git.psi.ch/sls_detectors_firmware/vhdl_library/blob/qsys/flow/flow_ctrl.vhd +/** ASIC Readout Control */ +#define BASE_ASIC_RDO (0x00500) // 0x1806_0500 - 0x1806_050F +// https://git.psi.ch/sls_detectors_firmware/mythen_III_mcb/blob/master/code/hdl/asic_rdo/asic_rdo.vhd + /* UDP datagram generator */ #define BASE_UDP_RAM (0x01000) // 0x1806_1000 - 0x1806_1FFF @@ -157,6 +161,53 @@ #define COORD_ID_OFST (16) // Not connected in firmware TODO #define COORD_ID_MSK (0x0000FFFF << COORD_ID_OFST) // Not connected in firmware TODO +/* ASIC Exposure Control registers + * --------------------------------------------------*/ + +/** ASIC Exposure Status register */ +#define ASIC_EXP_STATUS_REG (0x00 * REG_OFFSET + BASE_ASIC_EXP) + +#define ASIC_EXP_STAT_GATE_SRC_EXT_OFST (0) +#define ASIC_EXP_STAT_GATE_SRC_EXT_MSK (0x00000001 << ASIC_EXP_STAT_GATE_SRC_EXT_OFST) +#define ASIC_EXP_STAT_STO_LNGTH_OFST (16) +#define ASIC_EXP_STAT_STO_LNGTH_MSK (0x000000FF << ASIC_EXP_STAT_STO_LNGTH_OFST) +#define ASIC_EXP_STAT_RSCNTR_LNGTH_OFST (24) +#define ASIC_EXP_STAT_RSCNTR_LNGTH_MSK (0x000000FF << ASIC_EXP_STAT_RSCNTR_LNGTH_OFST) + +/** Gate 0 width register */ +#define ASIC_EXP_GATE_0_WIDTH_LSB_REG (0x01 * REG_OFFSET + BASE_ASIC_EXP) +#define ASIC_EXP_GATE_0_WIDTH_MSB_REG (0x02 * REG_OFFSET + BASE_ASIC_EXP) + +/** Gate 1 width register */ +#define ASIC_EXP_GATE_1_WIDTH_LSB_REG (0x03 * REG_OFFSET + BASE_ASIC_EXP) +#define ASIC_EXP_GATE_1_WIDTH_MSB_REG (0x04 * REG_OFFSET + BASE_ASIC_EXP) + +/** Gate 2 width register */ +#define ASIC_EXP_GATE_2_WIDTH_LSB_REG (0x05 * REG_OFFSET + BASE_ASIC_EXP) +#define ASIC_EXP_GATE_2_WIDTH_MSB_REG (0x06 * REG_OFFSET + BASE_ASIC_EXP) + +/** Gate 0 delay register */ +#define ASIC_EXP_GATE_0_DELAY_LSB_REG (0x07 * REG_OFFSET + BASE_ASIC_EXP) +#define ASIC_EXP_GATE_0_DELAY_MSB_REG (0x08 * REG_OFFSET + BASE_ASIC_EXP) + +/** Gate 1 delay register */ +#define ASIC_EXP_GATE_1_DELAY_LSB_REG (0x09 * REG_OFFSET + BASE_ASIC_EXP) +#define ASIC_EXP_GATE_1_DELAY_MSB_REG (0x0A * REG_OFFSET + BASE_ASIC_EXP) + +/** Gate 2 delay register */ +#define ASIC_EXP_GATE_2_DELAY_LSB_REG (0x0B * REG_OFFSET + BASE_ASIC_EXP) +#define ASIC_EXP_GATE_2_DELAY_MSB_REG (0x0C * REG_OFFSET + BASE_ASIC_EXP) + +/** Gate period register */ +#define ASIC_EXP_GATE_PERIOD_LSB_REG (0x0D * REG_OFFSET + BASE_ASIC_EXP) +#define ASIC_EXP_GATE_PERIOD_MSB_REG (0x0E * REG_OFFSET + BASE_ASIC_EXP) + +/** Number of Internal Gates register */ +#define ASIC_EXP_INT_GATE_NUMBER_REG (0x0F * REG_OFFSET + BASE_ASIC_EXP) + +/** Number of Internal Gates register */ +#define ASIC_EXP_EXT_GATE_NUMBER_REG (0x10 * REG_OFFSET + BASE_ASIC_EXP) + /* Pattern Control registers * --------------------------------------------------*/ @@ -325,4 +376,13 @@ #define SET_TRIGGER_DELAY_LSB_REG (0x32 * REG_OFFSET + BASE_FLOW_CONTROL) #define SET_TRIGGER_DELAY_MSB_REG (0x33 * REG_OFFSET + BASE_FLOW_CONTROL) + +/* ASIC Readout Control registers + * --------------------------------------------------*/ + +#define ASIC_RDO_CONFIG_REG (0x01 * REG_OFFSET + BASE_ASIC_RDO) + +#define ASICRDO_CNFG_RESSTRG_LNGTH_OFST (0) +#define ASICRDO_CNFG_RESSTRG_LNGTH_MSK (0x000000FF << ASICRDO_CNFG_RESSTRG_LNGTH_OFST) + // clang-format on \ No newline at end of file diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index 12302130c..e541b5d01 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -415,6 +415,7 @@ void setupDetector() { // defaults setHighVoltage(DEFAULT_HIGH_VOLTAGE); setDefaultDacs(); + setASICDefaults(); // dynamic range setDynamicRange(DEFAULT_DYNAMIC_RANGE); @@ -424,10 +425,15 @@ void setupDetector() { // Initialization of acquistion parameters setNumFrames(DEFAULT_NUM_FRAMES); setNumTriggers(DEFAULT_NUM_CYCLES); - setExpTime(DEFAULT_EXPTIME); setPeriod(DEFAULT_PERIOD); setDelayAfterTrigger(DEFAULT_DELAY_AFTER_TRIGGER); setTiming(DEFAULT_TIMING_MODE); + setNumIntGates(DEFAULT_INTERNAL_GATES); + setNumGates(DEFAULT_EXTERNAL_GATES); + for (int i = 0; i != 2; ++i) { + setExpTime(i, DEFAULT_GATE_WIDTH); + setGateDelay(i, DEFAULT_GATE_DELAY); + } } int setDefaultDacs() { @@ -446,6 +452,25 @@ int setDefaultDacs() { return ret; } +void setASICDefaults() { + uint32_t val = bus_r(ASIC_EXP_STATUS_REG); + val &= (~ASIC_EXP_STAT_STO_LNGTH_MSK); + val |= ((DEFAULT_ASIC_LATCHING_NUM_PULSES << ASIC_EXP_STAT_STO_LNGTH_OFST) & + ASIC_EXP_STAT_STO_LNGTH_MSK); + val &= (~ASIC_EXP_STAT_RSCNTR_LNGTH_MSK); + val |= + ((DEFAULT_ASIC_LATCHING_NUM_PULSES << ASIC_EXP_STAT_RSCNTR_LNGTH_OFST) & + ASIC_EXP_STAT_RSCNTR_LNGTH_MSK); + bus_w(ASIC_EXP_STATUS_REG, val); + + val = bus_r(ASIC_RDO_CONFIG_REG); + val &= (~ASICRDO_CNFG_RESSTRG_LNGTH_MSK); + val |= + ((DEFAULT_ASIC_LATCHING_NUM_PULSES << ASICRDO_CNFG_RESSTRG_LNGTH_OFST) & + ASICRDO_CNFG_RESSTRG_LNGTH_MSK); + bus_w(ASIC_RDO_CONFIG_REG, val); +} + /* firmware functions (resets) */ void cleanFifos() { @@ -783,40 +808,18 @@ int64_t getNumTriggers() { return get64BitReg(SET_CYCLES_LSB_REG, SET_CYCLES_MSB_REG); } -int setExpTime(int64_t val) { - if (val < 0) { - LOG(logERROR, ("Invalid exptime: %lld ns\n", (long long int)val)); - return FAIL; - } - LOG(logINFO, ("Setting exptime %lld ns\n", (long long int)val)); - val *= (1E-9 * getFrequency(SYSTEM_C0)); - setPatternWaitTime(0, val); - - // validate for tolerance - int64_t retval = getExpTime(); - val /= (1E-9 * getFrequency(SYSTEM_C0)); - if (val != retval) { - return FAIL; - } - return OK; -} - -int64_t getExpTime() { - return setPatternWaitTime(0, -1) / (1E-9 * getFrequency(SYSTEM_C0)); -} - int setPeriod(int64_t val) { if (val < 0) { LOG(logERROR, ("Invalid period: %lld ns\n", (long long int)val)); return FAIL; } LOG(logINFO, ("Setting period %lld ns\n", (long long int)val)); - val *= (1E-9 * FIXED_PLL_FREQUENCY); + val *= (1E-9 * getFrequency(SYSTEM_C2)); set64BitReg(val, SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG); // validate for tolerance int64_t retval = getPeriod(); - val /= (1E-9 * FIXED_PLL_FREQUENCY); + val /= (1E-9 * getFrequency(SYSTEM_C2)); if (val != retval) { return FAIL; } @@ -825,7 +828,165 @@ int setPeriod(int64_t val) { int64_t getPeriod() { return get64BitReg(SET_PERIOD_LSB_REG, SET_PERIOD_MSB_REG) / - (1E-9 * FIXED_PLL_FREQUENCY); + (1E-9 * getFrequency(SYSTEM_C2)); +} + +void setNumIntGates(int val) { + if (val > 0) { + LOG(logINFO, + ("Setting number of Internal Gates %lld\n", (long long int)val)); + bus_w(ASIC_EXP_INT_GATE_NUMBER_REG, val); + } +} + +void setNumGates(int val) { + if (val > 0) { + LOG(logINFO, ("Setting number of Gates %lld\n", (long long int)val)); + bus_w(ASIC_EXP_EXT_GATE_NUMBER_REG, val); + } +} + +int getNumExtGates() { return bus_r(ASIC_EXP_EXT_GATE_NUMBER_REG); } + +void updateGatePeriod() { + uint64_t max = 0; + for (int i = 0; i != 2; ++i) { + // TODO: only those counters enabled (when updated to mask in firmware) + uint64_t sum = getExpTime(i) + getGateDelay(i); + if (sum > max) { + max = sum; + } + } + LOG(logINFO, ("\tSetting Gate Period to %lld ns\n", (long long int)max)); + max *= (1E-9 * getFrequency(SYSTEM_C2)); + set64BitReg(max, ASIC_EXP_GATE_PERIOD_LSB_REG, + ASIC_EXP_GATE_PERIOD_MSB_REG); +} + +int setExptime(int gateIndex, int64_t val) { + uint32_t alsb = 0; + uint32_t amsb = 0; + switch (gateIndex) { + case 0: + alsb = ASIC_EXP_GATE_0_WIDTH_LSB_REG; + blsb = ASIC_EXP_GATE_0_WIDTH_MSB_REG; + break; + case 1: + alsb = ASIC_EXP_GATE_1_WIDTH_LSB_REG; + blsb = ASIC_EXP_GATE_1_WIDTH_MSB_REG; + break; + case 2: + alsb = ASIC_EXP_GATE_2_WIDTH_LSB_REG; + blsb = ASIC_EXP_GATE_2_WIDTH_MSB_REG; + break; + default: + LOG(logERROR, ("Invalid gate index: %d\n", gateIndex)); + return FAIL; + } + if (val < 0) { + LOG(logERROR, ("Invalid exptime (index:%d): %lld ns\n", gateIndex, + (long long int)val)); + return FAIL; + } + LOG(logINFO, ("Setting exptime %lld ns (index:%d)\n", (long long int)val, + gateIndex)); + val *= (1E-9 * getFrequency(SYSTEM_C2)); + set64BitReg(val, alsb, amsb); + + // validate for tolerance + int64_t retval = getExpTime(gateIndex); + val /= (1E-9 * getFrequency(SYSTEM_C2)); + if (val != retval) { + return FAIL; + } + + updateGatePeriod(); + + return OK; +} + +int64_t getExptime(int gateIndex) { + switch (gateIndex) { + case 0: + alsb = ASIC_EXP_GATE_0_WIDTH_LSB_REG; + blsb = ASIC_EXP_GATE_0_WIDTH_MSB_REG; + break; + case 1: + alsb = ASIC_EXP_GATE_1_WIDTH_LSB_REG; + blsb = ASIC_EXP_GATE_1_WIDTH_MSB_REG; + break; + case 2: + alsb = ASIC_EXP_GATE_2_WIDTH_LSB_REG; + blsb = ASIC_EXP_GATE_2_WIDTH_MSB_REG; + break; + default: + LOG(logERROR, ("Invalid gate index: %d\n", gateIndex)); + return -1; + } + return get64BitReg(alsb, amsb) / (1E-9 * getFrequency(SYSTEM_C2)); +} + +int setGateDelay(int gateIndex, int64_t val) { + uint32_t alsb = 0; + uint32_t amsb = 0; + switch (gateIndex) { + case 0: + alsb = ASIC_EXP_GATE_0_DELAY_LSB_REG; + blsb = ASIC_EXP_GATE_0_DELAY_MSB_REG; + break; + case 1: + alsb = ASIC_EXP_GATE_1_DELAY_LSB_REG; + blsb = ASIC_EXP_GATE_1_DELAY_MSB_REG; + break; + case 2: + alsb = ASIC_EXP_GATE_2_DELAY_LSB_REG; + blsb = ASIC_EXP_GATE_2_DELAY_MSB_REG; + break; + default: + LOG(logERROR, ("Invalid gate index: %d\n", gateIndex)); + return FAIL; + } + if (val < 0) { + LOG(logERROR, ("Invalid gate delay (index:%d): %lld ns\n", gateIndex, + (long long int)val)); + return FAIL; + } + LOG(logINFO, ("Setting gate delay %lld ns (index:%d)\n", (long long int)val, + gateIndex)); + val *= (1E-9 * getFrequency(SYSTEM_C2)); + set64BitReg(val, alsb, amsb); + + // validate for tolerance + int64_t retval = getGateDelay(gateIndex); + val /= (1E-9 * getFrequency(SYSTEM_C2)); + if (val != retval) { + return FAIL; + } + + updateGatePeriod(); + + return OK; +} + +int64_t getGateDelay(int gateIndex) { + switch (gateIndex) { + case 0: + alsb = ASIC_EXP_GATE_0_DELAY_LSB_REG; + blsb = ASIC_EXP_GATE_0_DELAY_MSB_REG; + break; + case 1: + alsb = ASIC_EXP_GATE_1_DELAY_LSB_REG; + blsb = ASIC_EXP_GATE_1_DELAY_MSB_REG; + break; + case 2: + alsb = ASIC_EXP_GATE_2_DELAY_LSB_REG; + blsb = ASIC_EXP_GATE_2_DELAY_MSB_REG; + break; + default: + LOG(logERROR, ("Invalid gate index: %d\n", gateIndex)); + return -1; + } + return get64BitReg(alsb, amsb) / (1E-9 * getFrequency(SYSTEM_C2)); } void setCounterMask(uint32_t arg) { @@ -852,6 +1013,8 @@ void setCounterMask(uint32_t arg) { bus_w(addr, bus_r(addr) & ~CONFIG_COUNTER_ENA_MSK); bus_w(addr, bus_r(addr) | val); LOG(logDEBUG, ("Config Reg: 0x%x\n", bus_r(addr))); + + updateGatePeriod(); } uint32_t getCounterMask() { @@ -897,12 +1060,12 @@ int setDelayAfterTrigger(int64_t val) { return FAIL; } LOG(logINFO, ("Setting delay after trigger %lld ns\n", (long long int)val)); - val *= (1E-9 * FIXED_PLL_FREQUENCY); + val *= (1E-9 * getFrequency(SYSTEM_C2)); set64BitReg(val, SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG); // validate for tolerance int64_t retval = getDelayAfterTrigger(); - val /= (1E-9 * FIXED_PLL_FREQUENCY); + val /= (1E-9 * getFrequency(SYSTEM_C2)); if (val != retval) { return FAIL; } @@ -911,7 +1074,7 @@ int setDelayAfterTrigger(int64_t val) { int64_t getDelayAfterTrigger() { return get64BitReg(SET_TRIGGER_DELAY_LSB_REG, SET_TRIGGER_DELAY_MSB_REG) / - (1E-9 * FIXED_PLL_FREQUENCY); + (1E-9 * getFrequency(SYSTEM_C2)); } int64_t getNumFramesLeft() { @@ -924,12 +1087,12 @@ int64_t getNumTriggersLeft() { int64_t getDelayAfterTriggerLeft() { return get64BitReg(GET_DELAY_LSB_REG, GET_DELAY_MSB_REG) / - (1E-9 * FIXED_PLL_FREQUENCY); + (1E-9 * getFrequency(SYSTEM_C2)); } int64_t getPeriodLeft() { return get64BitReg(GET_PERIOD_LSB_REG, GET_PERIOD_MSB_REG) / - (1E-9 * FIXED_PLL_FREQUENCY); + (1E-9 * getFrequency(SYSTEM_C2)); } int64_t getFramesFromStart() { @@ -1014,23 +1177,68 @@ void setTiming(enum timingMode arg) { if (arg != GET_TIMING_MODE) { switch (arg) { case AUTO_TIMING: - LOG(logINFO, ("Set Timing: Auto\n")); + LOG(logINFO, ("Set Timing: Auto (Int. Trigger, Int. Gating)\n")); bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) & ~EXT_SIGNAL_MSK); + bus_w(ASIC_EXP_STATUS_REG, + bus_r(ASIC_EXP_STATUS_REG) & ~ASIC_EXP_STAT_GATE_SRC_EXT_MSK); break; case TRIGGER_EXPOSURE: - LOG(logINFO, ("Set Timing: Trigger\n")); + LOG(logINFO, ("Set Timing: Trigger (Ext. Trigger, Int. Gating)\n")); bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) | EXT_SIGNAL_MSK); + bus_w(ASIC_EXP_STATUS_REG, + bus_r(ASIC_EXP_STATUS_REG) & ~ASIC_EXP_STAT_GATE_SRC_EXT_MSK); + break; + case GATED: + LOG(logINFO, ("Set Timing: Gating (Int. Trigger, Ext. Gating)\n")); + bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) & ~EXT_SIGNAL_MSK); + bus_w(ASIC_EXP_STATUS_REG, + bus_r(ASIC_EXP_STATUS_REG) | ASIC_EXP_STAT_GATE_SRC_EXT_MSK); + break; + case TRIGGER_GATED: + LOG(logINFO, + ("Set Timing: Trigger_Gating (Ext. Trigger, Ext. Gating)\n")); + bus_w(EXT_SIGNAL_REG, bus_r(EXT_SIGNAL_REG) | EXT_SIGNAL_MSK); + bus_w(ASIC_EXP_STATUS_REG, + bus_r(ASIC_EXP_STATUS_REG) | ASIC_EXP_STAT_GATE_SRC_EXT_MSK); break; default: LOG(logERROR, ("Unknown timing mode %d\n", arg)); + return; + } + // internal gating + if (arg == AUTO_TIMING || arg == TRIGGER_EXPOSURE) { + setNumGates(1); // should be in firmware + // TOOD: number of counters-> set appropriate gatewidth and + // gatedelay to 0 + setMaxGatePulseWidth(); + } + // external gating + else { } } } enum timingMode getTiming() { - if (bus_r(EXT_SIGNAL_REG) == EXT_SIGNAL_MSK) - return TRIGGER_EXPOSURE; - return AUTO_TIMING; + uint32_t extTrigger = (bus_r(EXT_SIGNAL_REG) | EXT_SIGNAL_MSK); + uint32_t extGate = + (bus_r(ASIC_EXP_STATUS_REG) | ASIC_EXP_STAT_GATE_SRC_EXT_MSK); + if (extTrigger) { + if (extGate) { + // external trigger, external gating + return TRIGGER_GATED; + } else { + // external trigger, internal gating + return TRIGGER_EXPOSURE; + } + } else { + if (extGate) { + // internal trigger, external gating + return GATED; + } else { + // internal trigger, internal gating + return AUTO_TIMING; + } + } } int configureMAC() { diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h index c99d35629..08e0fe224 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorServer_defs.h @@ -23,19 +23,23 @@ #define TYPE_NO_MODULE_STARTING_VAL (800) /** Default Parameters */ -#define DEFAULT_DYNAMIC_RANGE (24) -#define DEFAULT_NUM_FRAMES (1) -#define DEFAULT_NUM_CYCLES (1) -#define DEFAULT_EXPTIME (100 * 1000 * 1000) // ns -#define DEFAULT_PERIOD (2 * 1000 * 1000) // ns -#define DEFAULT_DELAY_AFTER_TRIGGER (0) -#define DEFAULT_HIGH_VOLTAGE (0) -#define DEFAULT_TIMING_MODE (AUTO_TIMING) -#define DEFAULT_READOUT_C0 (10) //(125000000) // rdo_clk, 125 MHz -#define DEFAULT_READOUT_C1 (10) //(125000000) // rdo_x2_clk, 125 MHz -#define DEFAULT_SYSTEM_C0 (5) //(250000000) // run_clk, 250 MHz -#define DEFAULT_SYSTEM_C1 (10) //(125000000) // chip_clk, 125 MHz -#define DEFAULT_SYSTEM_C2 (10) //(125000000) // sync_clk, 125 MHz +#define DEFAULT_INTERNAL_GATES (1) +#define DEFAULT_EXTERNAL_GATES (1) +#define DEFAULT_DYNAMIC_RANGE (24) +#define DEFAULT_NUM_FRAMES (1) +#define DEFAULT_NUM_CYCLES (1) +#define DEFAULT_GATE_WIDTH (100 * 1000 * 1000) // ns +#define DEFAULT_GATE_DELAY (0) +#define DEFAULT_PERIOD (2 * 1000 * 1000) // ns +#define DEFAULT_DELAY_AFTER_TRIGGER (0) +#define DEFAULT_HIGH_VOLTAGE (0) +#define DEFAULT_TIMING_MODE (AUTO_TIMING) +#define DEFAULT_READOUT_C0 (10) //(125000000) // rdo_clk, 125 MHz +#define DEFAULT_READOUT_C1 (10) //(125000000) // rdo_x2_clk, 125 MHz +#define DEFAULT_SYSTEM_C0 (5) //(250000000) // run_clk, 250 MHz +#define DEFAULT_SYSTEM_C1 (10) //(125000000) // chip_clk, 125 MHz +#define DEFAULT_SYSTEM_C2 (10) //(125000000) // sync_clk, 125 MHz +#define DEFAULT_ASIC_LATCHING_NUM_PULSES (10) /* Firmware Definitions */ #define IP_HEADER_SIZE (20) diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 25cfed686..b36ad13d6 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -115,6 +115,9 @@ void updateDataBytes(); defined(MOENCHD) int setDefaultDacs(); #endif +#ifdef MYTHEN3D +void setASICDefaults(); +#endif #if defined(GOTTHARD2D) || defined(EIGERD) int readConfigFile(); #endif @@ -201,10 +204,21 @@ void setNumFrames(int64_t val); int64_t getNumFrames(); void setNumTriggers(int64_t val); int64_t getNumTriggers(); +#ifndef MYTHEN3D int setExpTime(int64_t val); int64_t getExpTime(); +#endif int setPeriod(int64_t val); int64_t getPeriod(); +#ifdef MYTHEN3D +void setNumIntGates(int val); +void setNumGates(int val); +int getNumGates(); +int setExptime(int gateIndex, int64_t val); +int64_t getExptime(int gateIndex); +int setGateDelay(int gateIndex, int64_t val); +int64_t getGateDelay(int gateIndex); +#endif #ifdef GOTTHARD2D void setNumBursts(int64_t val); int64_t getNumBursts(); diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index dd5cd16d7..0de5a83b2 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -218,3 +218,9 @@ int get_num_channels(int); int update_rate_correction(int); int get_receiver_parameters(int); int start_pattern(int); +int set_num_gates(int); +int get_num_gates(int); +int set_gate_delay(int); +int get_gate_delay(int); +int get_exptime_all_gates(int); +int get_gate_delay_all_gates(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 8f0596109..2e92c912b 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -137,7 +137,6 @@ const char *getRunStateName(enum runStatus ind) { } } - void function_table() { flist[F_EXEC_COMMAND] = &exec_command; flist[F_GET_DETECTOR_TYPE] = &get_detector_type; @@ -330,6 +329,12 @@ void function_table() { flist[F_UPDATE_RATE_CORRECTION] = &update_rate_correction; flist[F_GET_RECEIVER_PARAMETERS] = &get_receiver_parameters; flist[F_START_PATTERN] = &start_pattern; + FLIST[F_SET_NUM_GATES] = &set_num_gates; + FLIST[F_GET_NUM_GATES] = &get_num_gates; + FLIST[F_SET_GATE_DELAY] = &set_gate_delay; + FLIST[F_GET_GATE_DELAY] = &get_gate_delay; + flist[F_GET_EXPTIME_ALL_GATES = &get_exptime_all_gates; + flist[F_GET_GATE_DELAY_ALL_GATES = &get_gate_delay_all_gates; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -510,6 +515,9 @@ int set_timing_mode(int file_des) { #ifdef EIGERD case GATED: case BURST_TRIGGER: +#elif MYTHEN3D + case GATED: + case TRIGGER_GATED: #endif setTiming(arg); break; @@ -2083,34 +2091,114 @@ int set_num_digital_samples(int file_des) { int get_exptime(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); + int gateIndex = -1; int64_t retval = -1; - // get only - retval = getExpTime(); - LOG(logDEBUG1, ("retval exptime %lld ns\n", (long long int)retval)); + if (receiveData(file_des, &gateIndex, sizeof(gateIndex), INT32) < 0) + return printSocketReadError(); + + // get only +#ifdef MYTHEN3D + if (gateIndex < 0 || gateIndex > 2) { + ret = FAIL; + sprintf(mess, + "Could not get exposure time. Invalid gate index %d. " + "Options [0-2]\n", + gateIndex); + LOG(logERROR, (mess)); + } else { + retval = getExptime(gateIndex); + LOG(logDEBUG1, ("retval exptime %lld ns\n", (long long int)retval)); + } +#else + if (gateIndex != -1) { + ret = FAIL; + sprintf(mess, "Could not get exposure time. Gate index not implemented " + "for this detector\n"); + LOG(logERROR, (mess)); + } else { + retval = getExpTime(); + LOG(logDEBUG1, ("retval exptime %lld ns\n", (long long int)retval)); + } +#endif return Server_SendResult(file_des, INT64, &retval, sizeof(retval)); } int set_exptime(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); - int64_t arg = -1; + int64_t args[2] = {-1, -1}; - if (receiveData(file_des, &arg, sizeof(arg), INT64) < 0) + if (receiveData(file_des, args, sizeof(args), INT64) < 0) return printSocketReadError(); - LOG(logDEBUG1, ("Setting exptime %lld ns\n", (long long int)arg)); + int gateIndex = args[0]; + int64_t val = args[1]; + LOG(logDEBUG1, ("Setting exptime %lld ns (gateIndex:%d)\n", + (long long int)val, gateIndex)); // only set if (Server_VerifyLock() == OK) { - ret = setExpTime(arg); - int64_t retval = getExpTime(); - LOG(logDEBUG1, ("retval exptime %lld ns\n", (long long int)retval)); - if (ret == FAIL) { +#ifdef MYTHEN3D + if (gateIndex < -1 || gateIndex > 2) { + ret = FAIL; sprintf(mess, - "Could not set exposure time. Set %lld ns, read %lld ns.\n", - (long long int)arg, (long long int)retval); + "Could not set exposure time. Invalid gate index %d. " + "Options [-1, 0-2]\n", + gateIndex); LOG(logERROR, (mess)); + } else { + // specific gate index + if (gateIndex != -1) { + ret = setExpTime(gateIndex, val); + int64_t retval = getExpTime(gateIndex); + LOG(logDEBUG1, + ("retval exptime %lld ns\n", (long long int)retval)); + if (ret == FAIL) { + sprintf(mess, + "Could not set exposure time. Set %lld ns, read " + "%lld ns.\n", + (long long int)val, (long long int)retval); + LOG(logERROR, (mess)); + } + } + // all gate indices + else { + for (int i = 0; i != 2; ++i) { + ret = setExpTime(i, val); + int64_t retval = getExpTime(i); + LOG(logDEBUG1, ("retval exptime %lld ns (index:%d)\n", + (long long int)retval, i)); + if (ret == FAIL) { + sprintf(mess, + "Could not set exptime. Set %lld ns, read %lld " + "ns.\n", + (long long int)val, (long long int)retval); + LOG(logERROR, (mess)); + break; + } + } + } } +#else + if (gateIndex != -1) { + ret = FAIL; + sprintf(mess, + "Could not get exposure time. Gate index not implemented " + "for this detector\n"); + LOG(logERROR, (mess)); + } else { + ret = setExpTime(val); + int64_t retval = getExpTime(); + LOG(logDEBUG1, ("retval exptime %lld ns\n", (long long int)retval)); + if (ret == FAIL) { + sprintf( + mess, + "Could not set exposure time. Set %lld ns, read %lld ns.\n", + (long long int)val, (long long int)retval); + LOG(logERROR, (mess)); + } + } +#endif } return Server_SendResult(file_des, INT64, NULL, 0); } @@ -7026,4 +7114,167 @@ int start_pattern(int file_des) { } #endif return Server_SendResult(file_des, INT32, NULL, 0); -} \ No newline at end of file +} + +int set_num_gates(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 number of gates %d\n", arg)); + +#if !defined(MYTHEN3D) + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + setNumGates(arg); + int retval = getNumGates(); + LOG(logDEBUG1, ("retval num gates %d\n", retval)); + validate(arg, retval, "set number of gates", DEC); + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} + +int get_num_gates(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; + +#if !defined(MYTHEN3D) + functionNotImplemented(); +#else + // get only + retval = getNumGates(); + LOG(logDEBUG1, ("retval num gates %d\n", retval)); +#endif + return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); +} + +int set_gate_delay(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t args[2] = {-1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT64) < 0) + return printSocketReadError(); + int gateIndex = args[0]; + int64_t val = args[1]; + LOG(logDEBUG1, ("Setting gate delay %lld ns (gateIndex:%d)\n", + (long long int)val, gateIndex)); + +#if !defined(MYTHEN3D) + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + if (gateIndex < -1 || gateIndex > 2) { + ret = FAIL; + sprintf(mess, + "Could not set gate delay. Invalid gate index %d. " + "Options [-1, 0-2]\n", + gateIndex); + LOG(logERROR, (mess)); + } else { + // specific gate index + if (gateIndex != -1) { + ret = setGateDelay(gateIndex, val); + int64_t retval = getGateDelay(gateIndex); + LOG(logDEBUG1, + ("retval exptime %lld ns\n", (long long int)retval)); + if (ret == FAIL) { + sprintf(mess, + "Could not set gate delay. Set %lld ns, read %lld " + "ns.\n", + (long long int)val, (long long int)retval); + LOG(logERROR, (mess)); + } + } + // all gate indices + else { + for (int i = 0; i != 2; ++i) { + ret = setGateDelay(i, val); + int64_t retval = getGateDelay(i); + LOG(logDEBUG1, ("retval gate delay %lld ns (index:%d)\n", + (long long int)retval, i)); + if (ret == FAIL) { + sprintf( + mess, + "Could not set gate delay. Set %lld ns, read %lld " + "ns.\n", + (long long int)val, (long long int)retval); + LOG(logERROR, (mess)); + break; + } + } + } + } +#endif + return Server_SendResult(file_des, INT64, NULL, 0); +} + +int get_gate_delay(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int gateIndex = -1; + int64_t retval = -1; + + if (receiveData(file_des, &gateIndex, sizeof(gateIndex), INT32) < 0) + return printSocketReadError(); + +#if !defined(MYTHEN3D) + functionNotImplemented(); +#else + // get only + if (gateIndex < 0 || gateIndex > 2) { + ret = FAIL; + sprintf(mess, + "Could not set gate delay. Invalid gate index %d. " + "Options [0-2]\n", + gateIndex); + LOG(logERROR, (mess)); + } else { + retval = getGateDelay(gateIndex); + LOG(logDEBUG1, + ("retval gate delay %lld ns\n", (long long int)retval)); + } +#endif + return Server_SendResult(file_des, INT64, &retval, sizeof(retval)); +} + +int get_exptime_all_gates(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t retvals[3] = {-1, -1, -1}; + +#if !defined(MYTHEN3D) + functionNotImplemented(); +#else + for (int i = 0; i != 2; ++i) { + retvals[i] = getExpTime(i); + LOG(logDEBUG1, ("retval exptime %lld ns (index:%d)\n", + (long long int)retvals[i], i)); + } +#endif + return Server_SendResult(file_des, INT64, retvals, sizeof(retvals)); +} + +int get_gate_delay_all_gates(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int64_t retvals[3] = {-1, -1, -1}; + +#if !defined(MYTHEN3D) + functionNotImplemented(); +#else + for (int i = 0; i != 2; ++i) { + retvals[i] = getGateDelay(i); + LOG(logDEBUG1, ("retval gate delay %lld ns (index:%d)\n", + (long long int)retvals[i], i)); + } +#endif + return Server_SendResult(file_des, INT64, retvals, sizeof(retvals)); +} diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index 0f8b1fb3e..bff65b132 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -203,7 +203,9 @@ class Detector { Result getTimingMode(Positions pos = {}) const; /** - * [Gotthard][Jungfrau][CTB][Moench] Options: AUTO_TIMING, TRIGGER_EXPOSURE + * [Gotthard][Jungfrau][CTB][Moench][Mythen3] Options: + * AUTO_TIMING, TRIGGER_EXPOSURE + * [Gotthard2] Options: AUTO_TIMING, TRIGGER_EXPOSURE, GATED, TRIGGER_GATED * [Eiger] Options: AUTO_TIMING, TRIGGER_EXPOSURE, GATED, BURST_TRIGGER */ void setTimingMode(defs::timingMode value, Positions pos = {}); @@ -991,6 +993,36 @@ class Detector { /** [Mythen3] countermask bit set for each counter enabled */ void setCounterMask(uint32_t countermask, Positions pos = {}); + Result getNumberOfGates(Positions pos = {}) const; + + /** [Mythen3] external gates in gating or trigger_gating mode (external + * gating) */ + void setNumberOfGates(int value, Positions pos = {}); + + /** [Mythen3] exptime for each gate signal in auto or trigger timing mode + * (internal gating). Gate index: 0-2 */ + Result getExptime(int gateIndex, Positions pos = {}) const; + + /** [Mythen3] exptime for each gate signal in auto or trigger timing mode + * (internal gating). Gate index: 0-2, -1 for all */ + void setExptime(int gateIndex, ns t, Positions pos = {}); + + /** [Mythen3] exptime for each gate signal in auto or trigger timing mode + * (internal gating). Gate index: 0-2, -1 for all */ + Result> getExptimeForAllGates(Positions pos = {}) const; + + /** [Mythen3] gate delay for each gate signal in auto or trigger timing mode + * (internal gating). Gate index: 0-2 */ + Result getGateDelay(int gateIndex, Positions pos = {}) const; + + /** [Mythen3] gate delay for each gate signal in auto or trigger timing mode + * (internal gating). Gate index: 0-2, -1 for all */ + void setGateDelay(int gateIndex, ns t, Positions pos = {}); + + /** [Mythen3] gate delay for each gate signal in auto or trigger timing mode + * (internal gating). Gate index: 0-2, -1 for all */ + Result> getGateDelayForAllGates(Positions pos = {}) const; + /************************************************** * * * CTB / Moench Specific * diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index c4bd6d5af..e0875d7fc 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -333,6 +333,109 @@ std::string CmdProxy::DetectorSize(int action) { /* acquisition parameters */ +std::string CmdProxy::Exptime(int action) { + int gateIndex = -1; + if (cmd == "exptime") { + gateIndex = -1; + } else if (cmd == "exptime1") { + gateIndex = 0; + } else if (cmd == "exptime2") { + gateIndex = 1; + } else if (cmd == "exptime3") { + gateIndex = 2; + } else { + throw sls::RuntimeError( + "Unknown command, use list to list all commands"); + } + + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + if (cmd == "exptime") { + os << "[duration] [(optional unit) " + "ns|us|ms|s]\n\t[Eiger][Jungfrau][Gotthard][Gotthard2][" + "Moench][Ctb] Exposure time" + "\n\t[Gotthard2] Uploaded to detector just before " + "acquisition starts" + "\n\t[Mythen3] Exposure time of all gate signals in auto and " + "trigger mode (internal gating)." + << '\n'; + } else if (cmd == "exptime1") { + os << "[n_value]\n\t[Mythen3] Exposure time of gate signal 1 in " + "auto and " + "trigger mode (internal gating)." + << '\n'; + } else if (cmd == "exptime2") { + os << "[n_value]\n\t[Mythen3] Exposure time of gate signal 2 in " + "auto and " + "trigger mode (internal gating)." + << '\n'; + } else { + os << "[n_value]\n\t[Mythen3] Exposure time of gate signal 3 in " + "auto and " + "trigger mode (internal gating)." + << '\n'; + } + } else if (action == defs::GET_ACTION) { + if (args.size() > 1) { + WrongNumberOfParameters(1); + } + // vector of exptimes + if (gateIndex == -1 & + det->getDetectorType().squash() == defs::MYTHEN3) { + auto t = det->getExptimeForAllGates({det_id}); + if (args.size() == 0) { + os << OutString(t) << '\n'; + } else if (args.size() == 1) { + os << OutString(t, args[0]) << '\n'; + } + } + // single exptime + else { + Result t; + if (gateIndex == -1) { + t = det->getExptime({det_id}); + } else { + t = det->getExptime(gateIndex, {det_id}); + } + if (args.size() == 0) { + os << OutString(t) << '\n'; + } else if (args.size() == 1) { + os << OutString(t, args[0]) << '\n'; + } + } + } else if (action == defs::PUT_ACTION) { + defs::detectorType type = det->getDetectorType().squash(); + if (args.size() == 1) { + std::string time_str(args[0]); + std::string unit = RemoveUnit(time_str); + auto t = StringTo(time_str, unit); + if (type == MYTHEN3) { + det->setExptime(gateIndex, t, {det_id}); + } else { + det->setExptime(t, {det_id}); + } + } else if (args.size() == 2) { + auto t = StringTo(args[0], args[1]); + if (type == MYTHEN3) { + det->setExptime(gateIndex, t, {det_id}); + } else { + det->setExptime(t, {det_id}); + } + } else { + WrongNumberOfParameters(2); + } + /* TODO: os << args << '\n'; (doesnt work for vectors in .h)*/ + if (args.size() > 1) { + os << args[0] << args[1] << '\n'; + } else { + os << args[0] << '\n'; + } + } else { + throw sls::RuntimeError("Unknown action"); + } +} + std::string CmdProxy::Speed(int action) { std::ostringstream os; os << cmd << ' '; @@ -1591,6 +1694,91 @@ std::string CmdProxy::Counters(int action) { return os.str(); } +std::string CmdProxy::GateDelay(int action) { + int gateIndex = -1; + if (cmd == "gatedelay") { + gateIndex = -1; + } else if (cmd == "gatedelay1") { + gateIndex = 0; + } else if (cmd == "gatedelay2") { + gateIndex = 1; + } else if (cmd == "gatedelay3") { + gateIndex = 2; + } else { + throw sls::RuntimeError( + "Unknown command, use list to list all commands"); + } + + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + if (cmd == "gatedelay") { + os << "[duration] [(optional unit) " + "ns|us|ms|s]\n\t[Mythen3] Gate Delay of all gate signals in " + "auto and " + "trigger mode (internal gating)." + << '\n'; + } else if (cmd == "gatedelay1") { + os << "[n_value]\n\t[Mythen3] Gate Delay of gate signal 1 in " + "auto and " + "trigger mode (internal gating)." + << '\n'; + } else if (cmd == "gatedelay2") { + os << "[n_value]\n\t[Mythen3] Gate Delay of gate signal 2 in " + "auto and " + "trigger mode (internal gating)." + << '\n'; + } else { + os << "[n_value]\n\t[Mythen3] Gate Delay of gate signal 3 in " + "auto and " + "trigger mode (internal gating)." + << '\n'; + } + } else if (action == defs::GET_ACTION) { + if (args.size() > 1) { + WrongNumberOfParameters(1); + } + // vector of gate delays + if (gateIndex == -1) { + auto t = det->getGateDelayForAllGates({det_id}); + if (args.size() == 0) { + os << OutString(t) << '\n'; + } else if (args.size() == 1) { + os << OutString(t, args[0]) << '\n'; + } + } + // single gate delay + else { + auto t = det->getGateDelay(gateIndex, {det_id}); + if (args.size() == 0) { + os << OutString(t) << '\n'; + } else if (args.size() == 1) { + os << OutString(t, args[0]) << '\n'; + } + } + } else if (action == defs::PUT_ACTION) { + if (args.size() == 1) { + std::string time_str(args[0]); + std::string unit = RemoveUnit(time_str); + auto t = StringTo(time_str, unit); + det->setGateDelay(gateIndex, t, {det_id}); + } else if (args.size() == 2) { + auto t = StringTo(args[0], args[1]); + det->setGateDelay(gateIndex, t, {det_id}); + } else { + WrongNumberOfParameters(2); + } + /* TODO: os << args << '\n'; (doesnt work for vectors in .h)*/ + if (args.size() > 1) { + os << args[0] << args[1] << '\n'; + } else { + os << args[0] << '\n'; + } + } else { + throw sls::RuntimeError("Unknown action"); + } +} + /* CTB / Moench Specific */ std::string CmdProxy::Samples(int action) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index cb71f1360..518deada8 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -570,7 +570,7 @@ class CmdProxy { {"acquire", &CmdProxy::acquire}, {"frames", &CmdProxy::frames}, {"triggers", &CmdProxy::triggers}, - {"exptime", &CmdProxy::exptime}, + {"exptime", &CmdProxy::Exptime}, {"period", &CmdProxy::period}, {"delay", &CmdProxy::delay}, {"framesl", &CmdProxy::framesl}, @@ -798,6 +798,14 @@ class CmdProxy { /* Mythen3 Specific */ {"counters", &CmdProxy::Counters}, + {"gates", &CmdProxy::gates}, + {"exptime1", &CmdProxy::Exptime}, + {"exptime2", &CmdProxy::Exptime}, + {"exptime3", &CmdProxy::Exptime}, + {"gatedelay", &CmdProxy::GateDelay}, + {"gatedelay1", &CmdProxy::GateDelay}, + {"gatedelay2", &CmdProxy::GateDelay}, + {"gatedelay3", &CmdProxy::GateDelay}, /* CTB/ Moench Specific */ {"samples", &CmdProxy::Samples}, @@ -916,6 +924,7 @@ class CmdProxy { std::string DetectorSize(int action); /* acquisition parameters */ std::string acquire(int action); + std::string Exptime(int action); std::string Speed(int action); std::string Adcphase(int action); std::string Dbitphase(int action); @@ -963,6 +972,7 @@ class CmdProxy { std::string BurstMode(int action); /* Mythen3 Specific */ std::string Counters(int action); + std::string GateDelay(int action); /* CTB/ Moench Specific */ std::string Samples(int action); /* CTB Specific */ @@ -1055,11 +1065,6 @@ class CmdProxy { "[n_triggers]\n\tNumber of triggers per aquire. Use " "timing command to set timing mode."); - TIME_COMMAND( - exptime, getExptime, setExptime, - "[duration] [(optional unit) ns|us|ms|s]\n\tExposure time" - "\n\t[Gotthard2] Uploaded to detector just before acquisition starts"); - TIME_COMMAND( period, getPeriod, setPeriod, "[duration] [(optional unit) ns|us|ms|s]\n\tPeriod between frames" @@ -1094,12 +1099,13 @@ class CmdProxy { " Period left for current frame." "\n\t[Gotthard2] only in continuous mode."); - INTEGER_COMMAND( - timing, getTimingMode, setTimingMode, - sls::StringTo, - "[auto|trigger|gating|burst_trigger]\n\tTiming Mode of " - "detector.\n\t[Jungfrau][Gotthard][Mythen3][Gotthard2][Ctb][Moench] " - "[auto|trigger]\n\t[Eiger] [auto|trigger|gating|burst_trigger]"); + INTEGER_COMMAND(timing, getTimingMode, setTimingMode, + sls::StringTo, + "[auto|trigger|gating|burst_trigger]\n\tTiming Mode of " + "detector.\n\t[Jungfrau][Gotthard][Mythen3][Ctb][Moench] " + "[auto|trigger]\n\t[Gotthard2] " + "[auto|trigger|gating|trigger_gating]\n\t[Eiger] " + "[auto|trigger|gating|burst_trigger]"); GET_COMMAND(maxadcphaseshift, getMaxADCPhaseShift, "\n\t[Jungfrau][CTB][Moench] Absolute maximum Phase shift of " @@ -1875,6 +1881,10 @@ class CmdProxy { /* Mythen3 Specific */ + INTEGER_COMMAND(gates, getNumberOfGates, setNumberOfGates, StringTo, + "[n_gates]\n\t[Mythen3] Number of external gates in gating " + "or trigger_gating mode (external gating)."); + /* CTB/ Moench Specific */ INTEGER_COMMAND( diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index d3648b0d2..8af4d6ac7 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -202,11 +202,11 @@ void Detector::setNumberOfTriggers(int64_t value) { } Result Detector::getExptime(Positions pos) const { - return pimpl->Parallel(&Module::getExptime, pos); + return pimpl->Parallel(&Module::getExptime, pos, -1); } void Detector::setExptime(ns t, Positions pos) { - pimpl->Parallel(&Module::setExptime, pos, t.count()); + pimpl->Parallel(&Module::setExptime, pos, -1, t.count()); } Result Detector::getPeriod(Positions pos) const { @@ -1258,6 +1258,39 @@ void Detector::setCounterMask(uint32_t countermask, Positions pos) { pimpl->Parallel(&Module::setCounterMask, pos, countermask); } +Result Detector::getNumberOfGates(Positions pos) const { + return pimpl->Parallel(&Module::getNumberOfGates, pos); +} + +void Detector::setNumberOfGates(int value, Positions pos) { + pimpl->Parallel(&Module::setNumberOfGates, pos, value); +} + +Result Detector::getExptime(int gateIndex, Positions pos) const { + return pimpl->Parallel(&Module::getExptime, pos, gateIndex); +} + +void Detector::setExptime(int gateIndex, ns t, Positions pos) { + pimpl->Parallel(&Module::setExptime, pos, gateIndex, t.count()); +} + +Result> Detector::getExptimeForAllGates(Positions pos) const { + return pimpl->Parallel(&Module::getExptimeForAllGates, pos); +} + +Result Detector::getGateDelay(int gateIndex, Positions pos) const { + return pimpl->Parallel(&Module::getGateDelay, pos, gateIndex); +} + +void Detector::setGateDelay(int gateIndex, ns t, Positions pos) { + pimpl->Parallel(&Module::setGateDelay, pos, gateIndex, t.count()); +} + +Result> +Detector::getGateDelayForAllGates(Positions pos) const { + return pimpl->Parallel(&Module::getGateDelayForAllGates, pos); +} + // CTB/ Moench Specific Result Detector::getNumberOfAnalogSamples(Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 43f74bd50..8131cbcaf 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1027,15 +1027,26 @@ void Module::setNumberOfDigitalSamples(int value) { } } -int64_t Module::getExptime() { return sendToDetector(F_GET_EXPTIME); } +int Module::getNumberOfGates() { return sendToDetector(F_GET_NUM_GATES); } -void Module::setExptime(int64_t value) { +void Module::setNumberOfGates(int value) { + LOG(logDEBUG1) << "Setting number of gates to " << value; + sendToDetector(F_SET_NUM_GATES, value, nullptr); +} + +int64_t Module::getExptime(int gateIndex) { + return sendToDetector(F_GET_EXPTIME, gateIndex); +} + +void Module::setExptime(int gateIndex, int64_t value) { int64_t prevVal = value; if (shm()->myDetectorType == EIGER) { prevVal = getExptime(); } - LOG(logDEBUG1) << "Setting exptime to " << value << "ns"; - sendToDetector(F_SET_EXPTIME, value, nullptr); + LOG(logDEBUG1) << "Setting exptime to " << value + << "ns (gateindex: " << gateIndex << ")"; + int64_t args[]{static_cast(gateIndex), value}; + sendToDetector(F_SET_EXPTIME, args, nullptr); if (shm()->useReceiverFlag) { LOG(logDEBUG1) << "Sending exptime to Receiver: " << value; sendToReceiver(F_RECEIVER_SET_EXPTIME, value, nullptr); @@ -1045,6 +1056,25 @@ void Module::setExptime(int64_t value) { } } +std::array Module::getExptimeForAllGates() { + return sendToDetector(F_GET_EXPTIME_ALL_GATES); +} + +int64_t Module::getGateDelay(int gateIndex) { + return sendToDetector(F_GET_GATE_DELAY, gateIndex); +} + +void Module::setGateDelay(int gateIndex, int64_t value) { + LOG(logDEBUG1) << "Setting gate delay to " << value + << "ns (gateindex: " << gateIndex << ")"; + int64_t args[]{static_cast(gateIndex), value}; + sendToDetector(F_SET_GATE_DELAY, args, nullptr); +} + +std::array Module::getGateDelayForAllGates() { + return sendToDetector(F_GET_GATE_DELAY_ALL_GATES); +} + int64_t Module::getPeriod() { return sendToDetector(F_GET_PERIOD); } void Module::setPeriod(int64_t value) { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index bdd81d651..fb42dd31c 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -419,9 +419,29 @@ class Module : public virtual slsDetectorDefs { /** [CTB] */ void setNumberOfDigitalSamples(int value); - int64_t getExptime(); + /** [Mythen3] */ + int getNumberOfGates(); - void setExptime(int64_t value); + /** [Mythen3] */ + void setNumberOfGates(int value); + + /** [Mythen3] gatIndex: 0-2, [Others]: -1 always */ + int64_t getExptime(int gateIndex); + + /** [Mythen3] gatIndex: -1 for all, 0-2, [Others]: -1 always */ + void setExptime(int gateIndex, int64_t value); + + /** [Mythen3] for all gates */ + std::array getExptimeForAllGates(); + + /** [Mythen3] gatIndex: 0-2 */ + int64_t getGateDelay(int gateIndex); + + /** [Mythen3] gatIndex: -1 for all, 0-2 */ + void setGateDelay(int gateIndex, int64_t value); + + /** [Mythen3] for all gates */ + std::array getGateDelayForAllGates(); int64_t getPeriod(); diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 9a0571f8f..57cf109f8 100644 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -241,6 +241,7 @@ typedef struct { TRIGGER_EXPOSURE, /**< trigger mode i.e. exposure is triggered */ GATED, /**< gated */ BURST_TRIGGER, /**< trigger a burst of frames */ + TRIGGER_GATED, /**< trigger and gating */ NUM_TIMING_MODES }; @@ -483,9 +484,9 @@ typedef struct { protected: #endif -// #ifndef MYROOT -// #include "sls_detector_funcs.h" -// #endif + // #ifndef MYROOT + // #include "sls_detector_funcs.h" + // #endif #ifdef __cplusplus }; diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index 4df1aab5c..0299b2a51 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -198,6 +198,12 @@ enum detFuncs { F_UPDATE_RATE_CORRECTION, F_GET_RECEIVER_PARAMETERS, F_START_PATTERN, + F_SET_NUM_GATES, + F_GET_NUM_GATES, + F_SET_GATE_DELAY, + F_GET_GATE_DELAY, + F_GET_EXPTIME_ALL_GATES, + F_GET_GATE_DELAY_ALL_GATES, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -492,6 +498,13 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_UPDATE_RATE_CORRECTION: return "F_UPDATE_RATE_CORRECTION"; case F_GET_RECEIVER_PARAMETERS: return "F_GET_RECEIVER_PARAMETERS"; case F_START_PATTERN: return "F_START_PATTERN"; + case F_SET_NUM_GATES: return "F_SET_NUM_GATES"; + case F_GET_NUM_GATES: return "F_GET_NUM_GATES"; + case F_SET_GATE_DELAY: return "F_SET_GATE_DELAY"; + case F_GET_GATE_DELAY: return "F_GET_GATE_DELAY"; + case F_GET_EXPTIME_ALL_GATES: return "F_GET_EXPTIME_ALL_GATES"; + case F_GET_GATE_DELAY_ALL_GATES: return "F_GET_GATE_DELAY_ALL_GATES"; + 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 934ecc944..d101b4cca 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -128,6 +128,8 @@ std::string ToString(const defs::timingMode s) { return std::string("gating"); case defs::BURST_TRIGGER: return std::string("burst_trigger"); + case defs::TRIGGER_GATED: + return std::string("trigger_gating"); default: return std::string("Unknown"); } @@ -318,6 +320,8 @@ template <> defs::timingMode StringTo(const std::string &s) { return defs::GATED; if (s == "burst_trigger") return defs::BURST_TRIGGER; + if (s == "trigger_gating") + return defs::TRIGGER_GATED; throw sls::RuntimeError("Unknown timing mode " + s); }