diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index 9f60f4d19..4f4d3b77b 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/config.txt b/slsDetectorServers/gotthard2DetectorServer/config.txt index bb41abf22..ebbfc5104 100755 --- a/slsDetectorServers/gotthard2DetectorServer/config.txt +++ b/slsDetectorServers/gotthard2DetectorServer/config.txt @@ -1,4 +1,4 @@ -#onchip dacs chip index value +#onchip dacs chip index value (max 0x3ff) vchip_comp_fe -1 0x137 vchip_opa_1st -1 0x000 vchip_opa_fd -1 0x134 @@ -6,7 +6,7 @@ vchip_comp_adc -1 0x3FF vchip_ref_comp_fe -1 0x100 vchip_cs -1 0x0D0 -#dacs +#dacs value (max 4096) vref_h_adc 2099 vb_comp_fe 0 vb_comp_adc 0 @@ -21,3 +21,9 @@ vref_cds 1200 vb_cs 2799 vb_opa_fd 0 vcom_adc2 1400 + +#configure adc chip index adc index value(max 0x7F) +confadc -1 -1 0x22 + +#vetoreference gain index value(max 0x3ff) +vetoref 1 0x0 diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index a115958b0..6bdad72eb 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -44,6 +44,8 @@ int defaultOnChipdacValues[ONCHIP_NDAC][NCHIP] = {0}; int injectedChannelsOffset = 0; int injectedChannelsIncrement = 0; int vetoReference[NCHIP][NCHAN]; +uint8_t adcConfiguration[NCHIP][NADC]; +int burstMode = 0; int detPos[2] = {0, 0}; int isInitCheckDone() { @@ -341,6 +343,7 @@ void setupDetector() { highvoltage = 0; injectedChannelsOffset = 0; injectedChannelsIncrement = 0; + burstMode = 0; { int i, j; @@ -360,6 +363,7 @@ void setupDetector() { for (i = 0; i < NCHIP; ++i) { for (j = 0; j < NCHAN; ++j) { vetoReference[i][j] = 0; + adcConfiguration[i][j] = 0; } } } @@ -380,7 +384,11 @@ void setupDetector() { // Default values setHighVoltage(DEFAULT_HIGH_VOLTAGE); - readConfigFile(); // also sets default dac and on chip dac values + // also sets default dac and on chip dac values + if (readConfigFile() == FAIL) { + return; + } + setBurstMode(1); // Initialization of acquistion parameters setNumFrames(DEFAULT_NUM_FRAMES); @@ -438,6 +446,8 @@ int readConfigFile() { memset(line, 0, LZ); char command[LZ]; + int nadcRead = 0; + // keep reading a line while (fgets(line, LZ, fd)) { @@ -456,8 +466,86 @@ int readConfigFile() { FILE_LOG(logDEBUG1, ("Command to process: (size:%d) %.*s\n", strlen(line), strlen(line) -1, line)); memset(command, 0, LZ); + // vetoref command + if (!strncmp(line, "vetoref", strlen("vetoref"))) { + int igain = 0; + int value = 0; + + // cannot scan values + if (sscanf(line, "%s %d 0x%x", command, &igain, &value) != 3) { + sprintf(initErrorMessage, "Could not scan vetoref commands from on-board server config file. Line:[%s].\n", line); + break; + } + //validations + if (igain < 0 || igain > 2) { + sprintf(initErrorMessage, "Could not set veto reference from on-board server config file. Invalid gain index. Line:[%s].\n", line); + break; + } + //validations + if (value > ADU_MAX_VAL) { + sprintf(initErrorMessage, "Could not set veto reference from on-board server config file. Invalid value (max 0x%x). Line:[%s].\n", ADU_MAX_VAL, line); + break; + } + if (setVetoReference(igain, value) == FAIL) { + sprintf(initErrorMessage, "Could not set veto reference from on-board server config file. Line:[%s].\n", line); + break; + } + } + + // confadc command + else if (!strncmp(line, "confadc", strlen("confadc"))) { + int ichip = -1; + int iadc = -1; + int value = 0; + + // cannot scan values + if (sscanf(line, "%s %d %d 0x%x", command, &ichip, &iadc, &value) != 4) { + sprintf(initErrorMessage, "Could not scan confadc commands from on-board server config file. Line:[%s].\n", line); + break; + } + //validations + if (ichip < -1 ||ichip >= NCHIP) { + sprintf(initErrorMessage, "Could not configure adc from on-board server config file. Invalid chip index. Line:[%s].\n", line); + break; + } + if (iadc < -1 || iadc >= NADC) { + sprintf(initErrorMessage, "Could not configure adc from on-board server config file. Invalid adc index. Line:[%s].\n", line); + break; + } + //validations + if (value > ASIC_ADC_MAX_VAL) { + sprintf(initErrorMessage, "Could not configure adc from on-board server config file. Invalid value (max 0x%x). Line:[%s].\n", ASIC_ADC_MAX_VAL, line); + break; + } + + int chipmin = 0; + int chipmax = NCHIP; + int adcmin = 0; + int adcmax = NADC; + + // specific chip + if (ichip != -1) { + chipmin = ichip; + chipmax = ichip + 1; + } + // specific adc + if (iadc != -1) { + adcmin = iadc; + adcmax = iadc + 1; + } + + int i, j; + for (i = chipmin; i < chipmax; ++i) { + for (j = adcmin; j < adcmax; ++j) { + adcConfiguration[i][j] = (uint8_t)value; + ++nadcRead; + } + } + } + + // vchip command - if (!strncmp(line, "vchip_", strlen("vchip_"))) { + else if (!strncmp(line, "vchip_", strlen("vchip_"))) { enum ONCHIP_DACINDEX idac = 0; int ichip = -1; @@ -550,6 +638,20 @@ int readConfigFile() { } fclose(fd); + if (!strlen(initErrorMessage)) { + if (nadcRead != NADC * NCHIP) { + sprintf(initErrorMessage, "Could not configure adc from on-board server config file. Insufficient adcconf commands. Read %d, expected %d\n", nadcRead, NADC * NCHIP); + } + } + { + int i = 0, j = 0; + for (i = 0; i < NCHIP; ++i) { + for (j = 0; j < NADC; ++j) { + FILE_LOG(logDEBUG1, ("adc read %d %d: 0x%02hhx\n", i, j, adcConfiguration[i][j])); + } + } + } + if (strlen(initErrorMessage)) { initError = FAIL; FILE_LOG(logERROR, ("%s\n\n", initErrorMessage)); @@ -1110,6 +1212,17 @@ void getInjectedChannels(int* offset, int* increment) { *increment = injectedChannelsIncrement; } +int setVetoReference(int gainIndex, int value) { + FILE_LOG(logINFO, ("Setting veto reference [chip:-1, G%d, value:0x%x]\n", gainIndex, value)); + int vals[NCHAN]; + memset(vals, 0, sizeof(vals)); + int ich = 0; + for (ich = 0; ich < NCHAN; ++ich) { + vals[ich] = value; + } + return setVetoPhoton(-1, gainIndex, vals); +} + int setVetoPhoton(int chipIndex, int gainIndex, int* values) { FILE_LOG(logINFO, ("Setting veto photon [chip:%d, G%d]\n", chipIndex, gainIndex)); @@ -1171,7 +1284,7 @@ int setVetoPhoton(int chipIndex, int gainIndex, int* values) { } // address at the end - buffer[len -1] |= (ASIC_VETO_REF_ADDR); + buffer[len - 1] |= (ASIC_VETO_REF_ADDR); if (ASIC_Driver_Set(chipIndex, sizeof(buffer), buffer) == FAIL) { return FAIL; @@ -1216,8 +1329,147 @@ int getVetoPhoton(int chipIndex, int* retvals) { return OK; } +int configureSingleADCDriver(int chipIndex) { + FILE_LOG(logINFO, ("Configuring ADC for %s chips [chipIndex:%d Burst Mode:%d]\n", chipIndex == -1 ? "All" : "Single", chipIndex, burstMode)); + + int ind = chipIndex; + if (ind == -1) { + ind = 0; + } + uint8_t values[NADC]; + memcpy(values, adcConfiguration + ind * NADC, NADC); + + // change adc values if continuous mode + { + int i = 0; + for (i = 0; i < NADC; ++i) { + if (!burstMode) { + values[i] |= ASIC_CONTINUOUS_MODE_MSK; + } + FILE_LOG(logDEBUG1, ("Value %d: 0x%02hhx\n", i, values[i])); + } + } + const int lenDataBitsPerADC = ASIC_ADC_MAX_BITS; // 7 + const int lenBits = lenDataBitsPerADC * NADC; // 224 + const int padding = 4; // due to address (4) to make it byte aligned + const int lenTotalBits = padding + lenBits + ASIC_ADDR_MAX_BITS; // 232 + const int len = lenTotalBits / 8; // 29 + + // assign each bit into 4 + 224 into byte array + uint8_t commandBytes[lenTotalBits]; + memset(commandBytes, 0, sizeof(commandBytes)); + int offset = padding; // bit offset for commandbytes + int ich = 0; + for (ich = 0; ich < NADC; ++ich) { + // loop through all bits in a value + int iBit = 0; + for (iBit = 0; iBit < lenDataBitsPerADC; ++iBit) { + commandBytes[offset++] = ((values[ich] >> (lenDataBitsPerADC - 1 - iBit)) & 0x1); + } + } + + // create command for 4 padding + 224 bits + 4 bits address = 232 bits = 29 bytes + char buffer[len]; + memset(buffer, 0, len); + offset = 0; + // loop through buffer elements + for (ich = 0; ich < len; ++ich) { + // loop through each bit in buffer element + int iBit = 0; + for (iBit = 0; iBit < 8; ++iBit) { + buffer[ich] |= (commandBytes[offset++] << (8 - 1 - iBit)); + } + } + + // address at the end + buffer[len - 1] |= (ASIC_CONF_ADC_ADDR); + + if (ASIC_Driver_Set(chipIndex, sizeof(buffer), buffer) == FAIL) { + return FAIL; + } + + return OK; +} + +int configureADC() { + FILE_LOG(logINFO, ("Configuring ADC \n")); + + int equal = 1; + { + int i = 0, j = 0; + for (i = 0; i < NADC; ++i) { + int val = adcConfiguration[0][i]; + for (j = 1; j < NCHIP; ++j) { + if (adcConfiguration[j][i] != val) { + equal = 0; + break; + } + } + } + } + if (equal) { + return configureSingleADCDriver(-1); + } else { + int i = 0; + for (i = 0; i < NCHIP; ++i) { + if (configureSingleADCDriver(i) == FAIL) { + return FAIL; + } + } + } + return OK; +} + + +int setBurstMode(int burst) { + FILE_LOG(logINFO, ("Setting %s Mode\n", burst == 1 ? "Burst" : "Continuous")); + int value = burst ? ASIC_GLOBAL_BURST_VALUE : ASIC_GLOBAL_CONT_VALUE; + + const int padding = 6; // due to address (4) to make it byte aligned + const int lenTotalBits = padding + ASIC_GLOBAL_SETT_MAX_BITS + ASIC_ADDR_MAX_BITS; // 4 + 6 + 4 = 16 + const int len = lenTotalBits / 8; // 2 + + // assign each bit into 4 + 224 into byte array + uint8_t commandBytes[lenTotalBits]; + memset(commandBytes, 0, sizeof(commandBytes)); + int offset = padding; // bit offset for commandbytes + int ich = 0; + // loop through all bits in a value + int iBit = 0; + for (iBit = 0; iBit < ASIC_GLOBAL_SETT_MAX_BITS; ++iBit) { + commandBytes[offset++] = ((value >> (ASIC_GLOBAL_SETT_MAX_BITS - 1 - iBit)) & 0x1); + } + + // create command for 4 padding + 224 bits + 4 bits address = 232 bits = 29 bytes + char buffer[len]; + memset(buffer, 0, len); + offset = 0; + // loop through buffer elements + for (ich = 0; ich < len; ++ich) { + // loop through each bit in buffer element + int iBit = 0; + for (iBit = 0; iBit < 8; ++iBit) { + buffer[ich] |= (commandBytes[offset++] << (8 - 1 - iBit)); + } + } + + // address at the end + buffer[len - 1] |= (ASIC_CONF_GLOBAL_SETT); + + int chipIndex = -1; + if (ASIC_Driver_Set(chipIndex, sizeof(buffer), buffer) == FAIL) { + return FAIL; + } + + burstMode = burst; + return configureADC(); +} + +int getBurstMode() { + return burstMode; +} /* aquisition */ int setDetectorPosition(int pos[]) { @@ -1230,6 +1482,9 @@ int* getDetectorPosition() { } int startStateMachine(){ + if (burstMode && getNumFrames() > MAX_FRAMES_IN_BURST_MODE) { + return FAIL; + } #ifdef VIRTUAL // create udp socket if(createUDPSocket(0) != OK) { diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index abce7198b..f0ca630a9 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -9,6 +9,7 @@ #define NCHAN (128) #define NCHIP (10) #define NDAC (16) +#define NADC (32) #define ONCHIP_NDAC (7) #define DYNAMIC_RANGE (16) #define HV_SOFT_MAX_VOLTAGE (200) @@ -21,6 +22,7 @@ #define ONCHIP_DAC_MAX_VAL (0x3FF) #define ADU_MAX_VAL (0xFFF) #define ADU_MAX_BITS (12) +#define MAX_FRAMES_IN_BURST_MODE (2720) /** Default Parameters */ @@ -85,12 +87,20 @@ enum PLLINDEX {READOUT_PLL, SYSTEM_PLL}; #define ASIC_ADDR_MAX_BITS (4) #define ASIC_CURRENT_INJECT_ADDR (0x9) #define ASIC_VETO_REF_ADDR (0xA) +#define ASIC_CONF_ADC_ADDR (0xB) +#define ASIC_CONF_GLOBAL_SETT (0xC) + #define ASIC_GAIN_MAX_BITS (2) #define ASIC_GAIN_MSK (0x3) - #define ASIC_G0_VAL ((0x0 & ASIC_GAIN_MSK) << ADU_MAX_BITS) #define ASIC_G1_VAL ((0x1 & ASIC_GAIN_MSK) << ADU_MAX_BITS) #define ASIC_G2_VAL ((0x3 & ASIC_GAIN_MSK) << ADU_MAX_BITS) +#define ASIC_CONTINUOUS_MODE_MSK (0x7) +#define ASIC_ADC_MAX_BITS (7) +#define ASIC_ADC_MAX_VAL (0x7F) +#define ASIC_GLOBAL_SETT_MAX_BITS (6) +#define ASIC_GLOBAL_BURST_VALUE (0x0) +#define ASIC_GLOBAL_CONT_VALUE (0x1E) /* Struct Definitions */ typedef struct udp_header_struct { diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 13d10f8a1..01cc84f0b 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -450,8 +450,13 @@ int setClockDivider(enum CLKINDEX ind, int val); int getClockDivider(enum CLKINDEX ind); int setInjectChannel(int offset, int increment); void getInjectedChannels(int* offset, int* increment); +int setVetoReference(int gainIndex, int value); int setVetoPhoton(int chipIndex, int gainIndex, int* values); int getVetoPhoton(int chipIndex, int* retvals); +int configureSingleADCDriver(int chipIndex); +int configureADC(); +int setBurstMode(int burst); +int getBurstMode(); #endif diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index 3b6a7e91e..ba833e0c4 100755 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -198,4 +198,7 @@ int get_on_chip_dac(int); int set_inject_channel(int); int get_inject_channel(int); int set_veto_photon(int); -int get_veto_photon(int); \ No newline at end of file +int get_veto_photon(int); +int set_veto_refernce(int); +int get_burst_mode(int); +int set_burst_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 427bf67cd..01db16f8d 100755 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -300,6 +300,9 @@ const char* getFunctionName(enum detFuncs func) { case F_GET_INJECT_CHANNEL: return "F_GET_INJECT_CHANNEL"; case F_SET_VETO_PHOTON: return "F_SET_VETO_PHOTON"; case F_GET_VETO_PHOTON: return "F_GET_VETO_PHOTON"; + case F_SET_VETO_REFERENCE: return "F_SET_VETO_REFERENCE"; + case F_GET_BURST_MODE: return "F_GET_BURST_MODE"; + case F_SET_BURST_MODE: return "F_SET_BURST_MODE"; default: return "Unknown Function"; } @@ -477,7 +480,10 @@ void function_table() { flist[F_GET_INJECT_CHANNEL] = &get_inject_channel; flist[F_SET_VETO_PHOTON] = &set_veto_photon; flist[F_GET_VETO_PHOTON] = &get_veto_photon; - + flist[F_SET_VETO_REFERENCE] = &set_veto_refernce; + flist[F_GET_BURST_MODE] = &get_burst_mode; + flist[F_SET_BURST_MODE] = &set_burst_mode; + // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { FILE_LOG(logERROR, ("The last detector function enum has reached its limit\nGoodbye!\n")); @@ -1760,10 +1766,14 @@ int start_acquisition(int file_des) { } else { ret = startStateMachine(); if (ret == FAIL) { -#if defined(CHIPTESTBOARDD) || defined(MOENCHD) +#if defined(CHIPTESTBOARDD) || defined(MOENCHD) || defined(VIRTUAL) sprintf(mess, "Could not start acquisition. Could not create udp socket in server. Check udp_dstip & udp_dstport.\n"); +#else +#if defined(GOTTHARD2D) + sprintf(mess, "Could not start acquisition due to #frames > %d in burst mode\n", MAX_FRAMES_IN_BURST_MODE); #else sprintf(mess, "Could not start acquisition\n"); +#endif #endif FILE_LOG(logERROR,(mess)); } @@ -1876,8 +1886,12 @@ int start_and_read_all(int file_des) { if (ret == FAIL) { #if defined(VIRTUAL) || defined(CHIPTESTBOARDD) || defined(MOENCHD) sprintf(mess, "Could not start acquisition. Could not create udp socket in server. Check udp_dstip & udp_dstport.\n"); +#else +#if defined(GOTTHARD2D) + sprintf(mess, "Could not start acquisition due to #frames > %d in burst mode\n", MAX_FRAMES_IN_BURST_MODE); #else sprintf(mess, "Could not start acquisition\n"); +#endif #endif FILE_LOG(logERROR,(mess)); } @@ -6307,4 +6321,85 @@ int get_veto_photon(int file_des) { sendData(file_des, retvals, sizeof(retvals), INT32); } return ret; +} + + +int set_veto_refernce(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int args[2] = {-1, -1}; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + FILE_LOG(logINFO, ("Setting Veto Reference: [G%d, value:0x%x]\n", args[0], args[1])); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + int gainIndex = args[0]; + int value = args[1]; + if (gainIndex < 0 || gainIndex > 2) { + ret = FAIL; + sprintf(mess, "Could not set veto reference. Invalid gain index %d\n", gainIndex); + FILE_LOG(logERROR, (mess)); + } else if (value > ADU_MAX_VAL) { + ret = FAIL; + sprintf(mess, "Could not set veto reference. Invalid ADU value 0x%x, must be 12 bit.\n", value); + FILE_LOG(logERROR, (mess)); + } else { + ret = setVetoReference(gainIndex, value); + if (ret == FAIL) { + sprintf(mess, "Could not set veto reference\n"); + FILE_LOG(logERROR, (mess)); + } + } + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); +} + + +int set_burst_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(); + FILE_LOG(logINFO, ("Setting burst mode: %d\n", arg)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + arg = arg == 0 ? 0 : 1; + ret = setBurstMode(arg); + if (ret == FAIL) { + sprintf(mess, "Could not set burst mode to %d\n", arg); + FILE_LOG(logERROR, (mess)); + } + } +#endif + return Server_SendResult(file_des, INT32, UPDATE, NULL, 0); +} + + +int get_burst_mode(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int retval = -1; + + FILE_LOG(logDEBUG1, ("Getting burst mode\n")); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + retval = getBurstMode(); + FILE_LOG(logDEBUG1, ("Get burst mode:%d\n", retval)); +#endif + return Server_SendResult(file_des, INT32, UPDATE, &retval, sizeof(retval)); } \ No newline at end of file diff --git a/slsDetectorSoftware/include/CmdProxy.h b/slsDetectorSoftware/include/CmdProxy.h index 599270807..5c7bbd021 100644 --- a/slsDetectorSoftware/include/CmdProxy.h +++ b/slsDetectorSoftware/include/CmdProxy.h @@ -778,6 +778,8 @@ class CmdProxy { /* Gotthard2 Specific */ {"inj_ch", &CmdProxy::InjectChannel}, {"vetophoton", &CmdProxy::VetoPhoton}, + {"vetoref", &CmdProxy::VetoReference}, + {"burstmode", &CmdProxy::burstmode}, /* CTB Specific */ {"samples", &CmdProxy::Samples}, @@ -927,7 +929,8 @@ class CmdProxy { std::string ClearROI(int action); /* Gotthard2 Specific */ std::string InjectChannel(int action); - std::string VetoPhoton(int action); + std::string VetoPhoton(int action); + std::string VetoReference(int action); /* CTB Specific */ std::string Samples(int action); std::string Dbitphase(int action); @@ -1509,6 +1512,9 @@ class CmdProxy { "[0, 1]\n\t[Gotthard] 1 adds channel intensity with precalculated values when taking an acquisition. Default is 0."); /* Gotthard2 Specific */ + INTEGER_COMMAND(burstmode, getBurstMode, setBurstMode, std::stoi, + "[0, 1]\n\t[Gotthard2] 1 sets to burst mode. 0 sets to continuous mode. Default is burst mode."); + /* CTB Specific */ INTEGER_COMMAND(asamples, getNumberOfAnalogSamples, setNumberOfAnalogSamples, std::stoi, diff --git a/slsDetectorSoftware/include/Detector.h b/slsDetectorSoftware/include/Detector.h index d0dc6dd09..ac6f35b31 100644 --- a/slsDetectorSoftware/include/Detector.h +++ b/slsDetectorSoftware/include/Detector.h @@ -891,7 +891,16 @@ class Detector { Result> getVetoPhoton(const int chipIndex, Positions pos = {}); /** [Gotthard2] energy in keV */ - void setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string& fname, Positions pos = {}); + void setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string& fname, Positions pos = {}); + + /** [Gotthard2] */ + void setVetoReference(const int gainIndex, const int value, Positions pos = {}); + + /** [Gotthard2] burst mode or continuous mode */ + void setBurstMode(bool enable, Positions pos = {}); + + /** [Gotthard2] */ + Result getBurstMode(Positions pos = {}); /************************************************** * * diff --git a/slsDetectorSoftware/include/slsDetector.h b/slsDetectorSoftware/include/slsDetector.h index 55862ae65..5d91b4a79 100755 --- a/slsDetectorSoftware/include/slsDetector.h +++ b/slsDetectorSoftware/include/slsDetector.h @@ -1116,6 +1116,15 @@ class slsDetector : public virtual slsDetectorDefs { /** [Gotthard2] energy in keV */ void setVetoPhoton(const int chipIndex, const int numPhotons, const int energy, const std::string& fname); + + void setVetoReference(const int gainIndex, const int value); + + /** [Gotthard2] burst mode or continuous mode */ + void setBurstMode(bool enable); + + /** [Gotthard2] */ + bool getBurstMode(); + /** * Set/get counter bit in detector (Gotthard) * @param i is -1 to get, 0 to reset and any other value to set the counter diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index f00e37d7e..872723dcc 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1066,6 +1066,25 @@ std::string CmdProxy::VetoPhoton(int action) { return os.str(); } +std::string CmdProxy::VetoReference(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[gain index] [12 bit value in hex] \n\t[Gotthard2] Set veto reference for all 128 channels for all chips." << '\n'; + } else if (action == defs::GET_ACTION) { + throw sls::RuntimeError("cannot get vetoref. Did you mean vetophoton?"); + } else if (action == defs::PUT_ACTION) { + if (args.size() != 2) { + WrongNumberOfParameters(2); + } + det->setVetoReference(std::stoi(args[0]), stoiHex(args[1]), {det_id}); + os << sls::ToString(args) << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + /* CTB Specific */ std::string CmdProxy::Samples(int action) { diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 038bc33a5..a959a3129 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -1104,6 +1104,18 @@ void Detector::setVetoPhoton(const int chipIndex, const int numPhotons, const in pimpl->Parallel(&slsDetector::setVetoPhoton, pos, chipIndex, numPhotons, energy, fname); } +void Detector::setVetoReference(const int gainIndex, const int value, Positions pos) { + pimpl->Parallel(&slsDetector::setVetoReference, pos, gainIndex, value); +} + +void Detector::setBurstMode(bool enable, Positions pos) { + pimpl->Parallel(&slsDetector::setBurstMode, pos, enable); +} + +Result Detector::getBurstMode(Positions pos) { + return pimpl->Parallel(&slsDetector::getBurstMode, pos); +} + // CTB Specific Result Detector::getNumberOfAnalogSamples(Positions pos) const { diff --git a/slsDetectorSoftware/src/slsDetector.cpp b/slsDetectorSoftware/src/slsDetector.cpp index eb14dacff..0c60ad405 100755 --- a/slsDetectorSoftware/src/slsDetector.cpp +++ b/slsDetectorSoftware/src/slsDetector.cpp @@ -2475,6 +2475,25 @@ void slsDetector::setVetoPhoton(const int chipIndex, const int numPhotons, const } } +void slsDetector::setVetoReference(const int gainIndex, const int value) { + int args[]{gainIndex, value}; + FILE_LOG(logDEBUG1) << "Setting veto reference [gainIndex: " << gainIndex << ", value: 0x" << std::hex << value << std::dec << ']'; + sendToDetector(F_SET_VETO_REFERENCE, args, nullptr); +} + +bool slsDetector::getBurstMode() { + int retval = -1; + sendToDetector(F_GET_BURST_MODE, nullptr, retval); + FILE_LOG(logDEBUG1) << "Burst mode:" << retval; + return static_cast(retval); +} + +void slsDetector::setBurstMode(bool enable) { + int arg = static_cast(enable); + FILE_LOG(logDEBUG1) << "Setting burst mode to " << arg; + sendToDetector(F_SET_BURST_MODE, arg, nullptr); +} + int slsDetector::setCounterBit(int cb) { int retval = -1; FILE_LOG(logDEBUG1) << "Sending counter bit " << cb; diff --git a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp index cf144fc85..139c38066 100644 --- a/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp +++ b/slsDetectorSoftware/tests/test-multiSlsDetectorClient.cpp @@ -9,6 +9,27 @@ auto GET = slsDetectorDefs::GET_ACTION; auto PUT = slsDetectorDefs::PUT_ACTION; +TEST_CASE("burstmode", "[.cmd][.gotthard2]") { + if (test::type == slsDetectorDefs::GOTTHARD2) { + REQUIRE_NOTHROW(multiSlsDetectorClient("burstmode 0", PUT)); + REQUIRE_NOTHROW(multiSlsDetectorClient("burstmode 1", PUT)); + REQUIRE_NOTHROW(multiSlsDetectorClient("burstmode", GET)); + } else { + REQUIRE_THROWS(multiSlsDetectorClient("burstmod", GET)); + } +} + +TEST_CASE("vetoref", "[.cmd][.gotthard2]") { + if (test::type == slsDetectorDefs::GOTTHARD2) { + REQUIRE_THROWS(multiSlsDetectorClient("vetoref 3 0x3ff", PUT)); // invalid chip index + REQUIRE_THROWS(multiSlsDetectorClient("vetoref 0 0xFFFF", PUT)); // invalid value + REQUIRE_NOTHROW(multiSlsDetectorClient("vetoref 1 0x010", PUT)); + REQUIRE_THROWS(multiSlsDetectorClient("vetoref", GET)); + } else { + REQUIRE_THROWS(multiSlsDetectorClient("vetoref 3 0x0", PUT)); + } +} + TEST_CASE("vetophoton", "[.cmd][.gotthard2]") { if (test::type == slsDetectorDefs::GOTTHARD2) { REQUIRE_THROWS(multiSlsDetectorClient("vetophoton 12 1 39950 examples/gotthard2_veto_photon.txt", PUT)); // invalid chip index diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index bd159ac5f..7162fefa8 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -181,6 +181,9 @@ enum detFuncs{ F_GET_INJECT_CHANNEL, F_SET_VETO_PHOTON, F_GET_VETO_PHOTON, + F_SET_VETO_REFERENCE, + F_GET_BURST_MODE, + F_SET_BURST_MODE, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this (detector server should not compile anyway) */ @@ -426,6 +429,9 @@ static const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_INJECT_CHANNEL: return "F_GET_INJECT_CHANNEL"; case F_SET_VETO_PHOTON: return "F_SET_VETO_PHOTON"; case F_GET_VETO_PHOTON: return "F_GET_VETO_PHOTON"; + case F_SET_VETO_REFERENCE: return "F_SET_VETO_REFERENCE"; + case F_GET_BURST_MODE: return "F_GET_BURST_MODE"; + case F_SET_BURST_MODE: return "F_SET_BURST_MODE"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";