From 755738a42e1bc7f38214ae86f8a5e5ce5611f0a6 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Tue, 22 Jun 2021 20:50:50 +0200 Subject: [PATCH] wip --- slsDetectorServers/eigerDetectorServer/Beb.c | 73 +++++++++++++++ slsDetectorServers/eigerDetectorServer/Beb.h | 2 + .../slsDetectorFunctionList.c | 40 ++++++++ .../eigerDetectorServer/xparameters.h | 14 ++- .../include/slsDetectorFunctionList.h | 2 + .../include/slsDetectorServer_funcs.h | 4 +- .../src/slsDetectorServer_funcs.c | 91 ++++++++++++++++++- slsDetectorSoftware/include/sls/Detector.h | 8 ++ slsDetectorSoftware/src/CmdProxy.cpp | 43 +++++++++ slsDetectorSoftware/src/CmdProxy.h | 7 +- slsDetectorSoftware/src/Detector.cpp | 35 ++++--- slsDetectorSoftware/src/Module.cpp | 62 +++++++------ slsDetectorSoftware/src/Module.h | 2 + .../tests/test-CmdProxy-eiger.cpp | 40 ++++++++ .../include/sls/sls_detector_funcs.h | 4 + 15 files changed, 378 insertions(+), 49 deletions(-) diff --git a/slsDetectorServers/eigerDetectorServer/Beb.c b/slsDetectorServers/eigerDetectorServer/Beb.c index cecadb5cd..fd8b76ea9 100644 --- a/slsDetectorServers/eigerDetectorServer/Beb.c +++ b/slsDetectorServers/eigerDetectorServer/Beb.c @@ -43,6 +43,8 @@ int Beb_deactivated_transmission_flowcontrol_10g = 0; int Beb_deactivated_transmission_delay_frame = 0; int Beb_deactivated_transmission_delay_left = 0; int Beb_deactivated_transmission_delay_right = 0; +int Beb_deactivated_left_datastream = 1; +int Beb_deactivated_right_datastream = 1; void BebInfo_BebInfo(struct BebInfo *bebInfo, unsigned int beb_num) { bebInfo->beb_number = beb_num; @@ -449,6 +451,77 @@ int Beb_GetActivate(int *retval) { return 1; } +int Beb_SetDataStream(int left, int enable) { + if (!Beb_activated) { + if (left) { + Beb_deactivated_left_datastream = enable; + } else { + Beb_deactivated_right_datastream = enable; + } + return 1; + } + if (left < 0) { + LOG(logERROR, ("Invalid left value\n")); + return 0; + } + if (enable < 0) { + LOG(logERROR, ("Invalid enable value\n")); + return 0; + } + u_int32_t *csp0base = 0; + int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR); + if (fd < 0) { + LOG(logERROR, ("Activate FAIL, could not open fd\n")); + return 0; + } else { + u_int32_t reg = XPAR_GPIO_P15_STREAMING_REG; + u_int32_t mask = + (left ? XPAR_GPIO_LFT_STRM_DSBL_MSK : XPAR_GPIO_RGHT_STRM_DSBL_MSK); + + u_int32_t value = Beb_Read32(csp0base, reg); + LOG(logDEBUG, ("data streaming register value before:%d\n", value)); + if (enable) + value |= mask; + else + value &= ~mask; + u_int32_t retval = Beb_Write32(csp0base, reg, value); + if (retval != value) { + LOG(logERROR, + ("Could not %s %s fpga datastream. Wrote 0x%x, read 0x%x\n", + (enable ? "enable" : "disable"), (left ? "left" : "right"), + value, retval)); + Beb_close(fd, csp0base); + } + } + Beb_close(fd, csp0base); + return 1; +} + +int Beb_GetDataStream(int left, int *retval) { + if (!Beb_activated) { + if (left) { + return Beb_deactivated_left_datastream; + } else { + return Beb_deactivated_right_datastream; + } + } + u_int32_t *csp0base = 0; + int fd = Beb_open(&csp0base, XPAR_PLB_GPIO_SYS_BASEADDR); + if (fd < 0) { + LOG(logERROR, ("Activate FAIL, could not open fd\n")); + return 0; + } else { + u_int32_t reg = XPAR_GPIO_P15_STREAMING_REG; + u_int32_t mask = + (left ? XPAR_GPIO_LFT_STRM_DSBL_MSK : XPAR_GPIO_RGHT_STRM_DSBL_MSK); + + u_int32_t value = Beb_Read32(csp0base, reg); + *retval = (value & mask) ? 1 : 0; + } + Beb_close(fd, csp0base); + return 1; +} + int Beb_Set32bitOverflow(int val) { if (!Beb_activated) return val; diff --git a/slsDetectorServers/eigerDetectorServer/Beb.h b/slsDetectorServers/eigerDetectorServer/Beb.h index 44eb42ad1..10f83a5b3 100644 --- a/slsDetectorServers/eigerDetectorServer/Beb.h +++ b/slsDetectorServers/eigerDetectorServer/Beb.h @@ -41,6 +41,8 @@ int Beb_SetTop(enum TOPINDEX ind); int Beb_SetMaster(enum MASTERINDEX ind); int Beb_SetActivate(int enable); int Beb_GetActivate(int *retval); +int Beb_SetDataStream(int left, int enable); +int Beb_GetDataStream(int left, int *retval); int Beb_Set32bitOverflow(int val); int Beb_GetTenGigaFlowControl(); diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index e06df6040..2365bb897 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -91,6 +91,8 @@ int eiger_virtual_test_mode = 0; int eiger_virtual_quad_mode = 0; int eiger_virtual_read_nlines = 256; int eiger_virtual_interrupt_subframe = 0; +int eiger_virtual_left_datastream = 1; +int eiger_virtual_right_datastream = 1; #endif int isInitCheckDone() { return initCheckDone; } @@ -2048,6 +2050,44 @@ int getActivate(int *retval) { return OK; } +int setDataStream(int left, int enable) { + if (enable < 0) { + LOG(logERROR, ("Invalid setDataStream enable argument: %d\n", enable)); + return FAIL; + } + if (left < 0) { + LOG(logERROR, ("Invalid setDataStream left argument: %d\n", left)); + return FAIL; + } +#ifdef VIRTUAL + if (left) { + eiger_virtual_left_datastream = enable; + } else { + eiger_virtual_right_datastream = enable; + } +#else + if (!Beb_SetDataStream(left, enable)) { + return FAIL; + } +#endif + return OK; +} + +int getDataStream(int left, int *retval) { +#ifdef VIRTUAL + if (left) { + *retval = eiger_virtual_left_datastream; + } else { + *retval = eiger_virtual_right_datastream; + } +#endif + if (!Beb_GetDataStream(left, retval)) { + return FAIL; + } +#endif + return OK; +} + int getTenGigaFlowControl() { #ifdef VIRTUAL return eiger_virtual_transmission_flowcontrol_10g; diff --git a/slsDetectorServers/eigerDetectorServer/xparameters.h b/slsDetectorServers/eigerDetectorServer/xparameters.h index 67a826283..d293257d2 100644 --- a/slsDetectorServers/eigerDetectorServer/xparameters.h +++ b/slsDetectorServers/eigerDetectorServer/xparameters.h @@ -35,7 +35,7 @@ XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR /* Definitions for peripheral PLB_BRAM_10G */ #define XPAR_PLB_BRAM_10G_MEM0_BASEADDR 0xD4100000 -#define XPAR_PLB_BRAM_10G_MEM0_HIGHADDR 0xD410FFFF +#define XPAR_PLB_BRAM_10G_MEM0_HIGHADDR /* Definitions for peripheral PLB_BRAM_TEMAC */ #define XPAR_PLB_BRAM_TEMAC_MEM0_BASEADDR 0xD4000000 @@ -45,6 +45,18 @@ XPAR_PLB_LL_FIFO_AURORA_DUAL_CTRL_FEB_LEFT_BASEADDR #define XPAR_PLB_GPIO_SYS_BASEADDR 0xD1000000 #define XPAR_PLB_GPIO_SYS_HIGHADDR 0xD100FFFF +// data streaming register +// clang-format off +#define XPAR_GPIO_P15_STREAMING_REG 0x01e0 +#define XPAR_GPIO_FRAME_PKT_ENBL_OFST (0) +#define XPAR_GPIO_FRAME_PKT_ENBL_MSK (0x00000001 << XPAR_GPIO_FRAME_PKT_ENBL_OFST) +#define XPAR_GPIO_RGHT_STRM_DSBL_OFST (1) +#define XPAR_GPIO_RGHT_STRM_DSBL_MSK (0x00000001 << XPAR_GPIO_RGHT_STRM_DSBL_OFST) +#define XPAR_GPIO_LFT_STRM_DSBL_OFST (2) +#define XPAR_GPIO_LFT_STRM_DSBL_MSK (0x00000001 << XPAR_GPIO_LFT_STRM_DSBL_OFST) + +// clang-format on + /** Command Generator */ #define XPAR_CMD_GENERATOR 0xC5000000 diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 0a81667f5..f9eef826c 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -472,6 +472,8 @@ int getAllTrimbits(); int getBebFPGATemp(); int setActivate(int enable); int getActivate(int *retval); +int getDataStream(int left, int *retval); +int setDataStream(int left, int enable); // gotthard specific - adc phase #elif GOTTHARDD diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index ffa18b91f..395378476 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -246,4 +246,6 @@ int get_all_threshold_energy(int); int get_master(int); int get_csr(); int set_gain_caps(int); -int get_gain_caps(int); \ No newline at end of file +int get_gain_caps(int); +int get_datastream(int); +int set_datastream(int); diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 0eb966214..79c836142 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -373,6 +373,8 @@ void function_table() { flist[F_GET_CSR] = &get_csr; flist[F_SET_GAIN_CAPS] = &set_gain_caps; flist[F_GET_GAIN_CAPS] = &get_gain_caps; + flist[F_GET_DATASTREAM] = &get_datastream; + flist[F_SET_DATASTREAM] = &set_datastream; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -3038,13 +3040,13 @@ int set_pattern_loop_addresses(int file_des) { else { // set if (startAddr >= 0 && stopAddr >= 0) { - ret = validate_setPatternLoopAddresses(mess, loopLevel, startAddr, - stopAddr); + ret = validate_setPatternLoopAddresses(mess, loopLevel, + startAddr, stopAddr); } // get if (ret == OK) { - ret = validate_getPatternLoopAddresses(mess, loopLevel, &retvals[0], - &retvals[1]); + ret = validate_getPatternLoopAddresses( + mess, loopLevel, &retvals[0], &retvals[1]); } } } @@ -8210,3 +8212,84 @@ int get_gain_caps(int file_des) { #endif return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } + +int get_datastream(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = -1; + int retval = -1; + + if (receiveData(file_des, args, sizeof(args), INT32) < 0) + return printSocketReadError(); + LOG(logDEBUG1, ("Getting data stream enable [left:%d]\n", arg)); + +#ifndef EIGERD + functionNotImplemented(); +#else + // get only + int leftFpga = arg; + if (leftFpga != 0 && leftFpga != 1) { + ret = FAIL; + sprintf( + mess, + "Could not get data stream enable. Invalid side %d. Left argument" + "should be 0 or 1.\n", + leftFpga); + LOG(logERROR, (mess)); + } else { + retval = getDataStream(leftFpga, adcIndex); + LOG(logDEBUG1, ("datastream (%s) retval: %u\n", + (left ? "left" : "right"), retval)); + } +#endif + return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); +} + +int set_datastream(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(); + LOG(logDEBUG1, ("Setting data stream enable [left:%d, enable:%d]\n", + args[0], args[1])); + +#ifndef EIGERD + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + int leftFpga = args[0]; + int enable = args[1]; + char msg[256]; + memset(msg, 0, sizeof(msg)); + sprintf(msg, "%s %s fpga datastream", (enable ? "enable" : "disable"), + (leftFpga ? "left" : "right")); + if (leftFpga != 0 && leftFpga != 1) { + ret = FAIL; + sprintf(mess, + "Could not %s. Invalid side %d. Left argument should be 0 " + "or 1.\n", + msg, leftFpga); + LOG(logERROR, (mess)); + } else if (enable != 0 && enable != 1) { + ret = FAIL; + sprintf(mess, "Could not %s. Invalid enable %d. \n", msg, enable); + LOG(logERROR, (mess)); + } else { + ret = setDataStream(leftFpga, enable); + if (ret == FAIL) { + sprintf(mess, "Could not %s\n", msg); + LOG(logERROR, (mess)); + } else { + int retval = getDataStream(leftFpga); + LOG(logDEBUG1, ("%s retval: %u\n", + msg, retval)); + validate(&ret, mess, enable, retval, msg, DEC); + } + } + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} \ No newline at end of file diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index 434c391e4..9b4073c14 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1056,6 +1056,14 @@ class Detector { /** [Eiger] Sets detector size to a quad. 0 (disabled) is default. (Specific * hardware required). */ void setQuad(const bool enable); + + /** [Eiger] */ + Result getDataStream(const bool left, Positions pos = {}) const; + + /** [Eiger] enable or disable data streaming from left or right of detector + */ + void setDataStream(const bool enable, const bool left, Positions pos = {}); + ///@{ /** @name Jungfrau Specific */ diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 629bd4233..1aa7b1f81 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1555,6 +1555,49 @@ std::string CmdProxy::Quad(int action) { return os.str(); } +std::string CmdProxy::DataStream(int action) { + std::ostringstream os; + os << cmd << ' '; + bool left = true; + if (action == defs::HELP_ACTION) { + os << "[0, 1] [left|right]\n\t[Eiger] Enables or disables data " + "streaming from left or/and right side of detector. 1 (enabled) " + "by default." + << '\n'; + } else if (action == defs::GET_ACTION) { + if (args.size() != 1) { + WrongNumberOfParameters(1); + } + // TODO, enum for "left and right?" + if (args[0] == "left") { + left = true; + } else if (args[0] == "right") { + left = false; + } else { + throw sls::RuntimeError("Unknown data argument " + args[0]); + } + auto t = det->getDataStream(left, std::vector{det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + if (args.size() != 2) { + WrongNumberOfParameters(2); + } + if (args[1] == "left") { + left = true; + } else if (args[1] == "right") { + left = false; + } else { + throw sls::RuntimeError("Unknown data argument " + args[1]); + } + det->setDataStream(left, StringTo(args[0]), + std::vector{det_id}); + os << args.front() << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + /* Jungfrau Specific */ std::string CmdProxy::TemperatureEvent(int action) { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index da5d38b7e..0ef62d6ba 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -571,7 +571,6 @@ class CmdProxy { return ToString(value, unit); } - using FunctionMap = std::map; using StringMap = std::map; @@ -915,6 +914,7 @@ class CmdProxy { {"pulsenmove", &CmdProxy::PulsePixelAndMove}, {"pulsechip", &CmdProxy::PulseChip}, {"quad", &CmdProxy::Quad}, + {"datastream", &CmdProxy::DataStream}, /* Jungfrau Specific */ {"temp_threshold", &CmdProxy::temp_threshold}, @@ -1109,6 +1109,7 @@ class CmdProxy { std::string PulsePixelAndMove(int action); std::string PulseChip(int action); std::string Quad(int action); + std::string DataStream(int action); /* Jungfrau Specific */ std::string TemperatureEvent(int action); /* Gotthard Specific */ @@ -1445,8 +1446,8 @@ class CmdProxy { "and automatically returns to idle at the end of readout."); EXECUTE_SET_COMMAND(stop, stopDetector, - "\n\tAbort detector acquisition. Status changes " - "to IDLE or STOPPED. Goes to stop server."); + "\n\tAbort detector acquisition. Status changes " + "to IDLE or STOPPED. Goes to stop server."); GET_COMMAND(rx_framescaught, getFramesCaught, "\n\tNumber of frames caught by receiver."); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 4cc64e6bc..9ed070545 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -675,11 +675,11 @@ void Detector::stopReceiver() { pimpl->Parallel(&Module::stopReceiver, {}); } void Detector::startDetector() { auto detector_type = getDetectorType().squash(); - if (detector_type == defs::MYTHEN3 && size() > 1){ + if (detector_type == defs::MYTHEN3 && size() > 1) { auto is_master = getMaster(); std::vector master; std::vector slaves; - for(int i=0; iParallel(&Module::startAcquisition, slaves); pimpl->Parallel(&Module::startAcquisition, master); - }else{ + } else { pimpl->Parallel(&Module::startAcquisition, {}); } - } void Detector::startDetectorReadout() { pimpl->Parallel(&Module::startReadout, {}); } -void Detector::stopDetector(Positions pos) { pimpl->Parallel(&Module::stopAcquisition, pos); } +void Detector::stopDetector(Positions pos) { + pimpl->Parallel(&Module::stopAcquisition, pos); +} Result Detector::getDetectorStatus(Positions pos) const { return pimpl->Parallel(&Module::getRunStatus, pos); @@ -733,8 +734,10 @@ Result Detector::getScan(Positions pos) const { } void Detector::setScan(const defs::scanParameters t) { - if(getDetectorType().squash() == defs::MYTHEN3 && size()>1 && t.enable != 0){ - throw DetectorError("Scan is only allowed for single module Mythen 3 because of synchronization"); + if (getDetectorType().squash() == defs::MYTHEN3 && size() > 1 && + t.enable != 0) { + throw DetectorError("Scan is only allowed for single module Mythen 3 " + "because of synchronization"); } pimpl->Parallel(&Module::setScan, {}, t); } @@ -1366,6 +1369,15 @@ void Detector::setQuad(const bool enable) { pimpl->Parallel(&Module::setQuad, {}, enable); } +Result Detector::getDataStream(const bool left, Positions pos) const { + return pimpl->Parallel(&Module::getDataStream, pos, left); +} + +void Detector::setDataStream(const bool enable, const bool left, + Positions pos) { + pimpl->Parallel(&Module::setDataStream, pos, enable, left); +} + // Jungfrau Specific Result Detector::getThresholdTemperature(Positions pos) const { @@ -1611,23 +1623,22 @@ Detector::getGateDelayForAllGates(Positions pos) const { return pimpl->Parallel(&Module::getGateDelayForAllGates, pos); } -Result Detector::getMaster(Positions pos) const{ +Result Detector::getMaster(Positions pos) const { return pimpl->Parallel(&Module::isMaster, pos); } -Result Detector::getChipStatusRegister(Positions pos) const{ +Result Detector::getChipStatusRegister(Positions pos) const { return pimpl->Parallel(&Module::getChipStatusRegister, pos); } -void Detector::setGainCaps(int caps, Positions pos){ +void Detector::setGainCaps(int caps, Positions pos) { return pimpl->Parallel(&Module::setGainCaps, pos, caps); } -Result Detector::getGainCaps(Positions pos){ +Result Detector::getGainCaps(Positions pos) { return pimpl->Parallel(&Module::getGainCaps, pos); } - // CTB/ Moench Specific Result Detector::getNumberOfAnalogSamples(Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index bb43ad31a..125f5f886 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -352,37 +352,39 @@ void Module::setAllThresholdEnergy(std::array e_eV, std::copy(e_eV.begin(), e_eV.end(), myMod.eV); LOG(logDEBUG) << "ev:" << ToString(myMod.eV); - //check for trimbits that are out of range + // check for trimbits that are out of range bool out_of_range = false; - for(int i = 0; i!=myMod.nchan; ++i){ - if (myMod.chanregs[i]<0){ + for (int i = 0; i != myMod.nchan; ++i) { + if (myMod.chanregs[i] < 0) { myMod.chanregs[i] = 0; out_of_range = true; - }else if(myMod.chanregs[i]>63){ - myMod.chanregs[i]=63; + } else if (myMod.chanregs[i] > 63) { + myMod.chanregs[i] = 63; out_of_range = true; } } - if (out_of_range){ - LOG(logWARNING) << "Some trimbits were out of range after interpolation, these have been replaced with 0 or 63."; + if (out_of_range) { + LOG(logWARNING) + << "Some trimbits were out of range after interpolation, these " + "have been replaced with 0 or 63."; } - //check dacs + // check dacs out_of_range = false; - for (auto dac : {M_VTRIM,M_VTH1,M_VTH2, M_VTH3}){ - if (myMod.dacs[dac] < 600){ + for (auto dac : {M_VTRIM, M_VTH1, M_VTH2, M_VTH3}) { + if (myMod.dacs[dac] < 600) { myMod.dacs[dac] = 600; out_of_range = true; - }else if(myMod.dacs[dac] > 2400){ + } else if (myMod.dacs[dac] > 2400) { myMod.dacs[dac] = 2400; out_of_range = true; } } - if (out_of_range){ - LOG(logWARNING) << "Some dacs were out of range after interpolation, these have been replaced with 600 or 2400."; + if (out_of_range) { + LOG(logWARNING) << "Some dacs were out of range after interpolation, " + "these have been replaced with 600 or 2400."; } - setModule(myMod, trimbits); if (getSettings() != isettings) { throw RuntimeError("setThresholdEnergyAndSettings: Could not set " @@ -412,7 +414,8 @@ void Module::loadSettingsFile(const std::string &fname) { if (shm()->myDetectorType == MYTHEN3) { serialNumberWidth = 4; } - if ((fname.find(".sn") == std::string::npos) && (fname.find(".trim") == std::string::npos)) { + if ((fname.find(".sn") == std::string::npos) && + (fname.find(".trim") == std::string::npos)) { ostfn << ".sn" << std::setfill('0') << std::setw(serialNumberWidth) << std::dec << getSerialNumber(); } @@ -1504,6 +1507,15 @@ void Module::setQuad(const bool enable) { } } +bool Module::getDataStream(const bool left) const { + return sendToDetector(F_GET_DATASTREAM, static_cast(left)); +} + +void Module::setDataStream(const bool enable, const bool left) { + int args[]{static_cast(enable), static_cast(left)}; + sendToDetector(F_GET_DATASTREAM, args, nullptr); +} + // Jungfrau Specific int Module::getThresholdTemperature() const { @@ -1994,21 +2006,17 @@ std::array Module::getGateDelayForAllGates() const { return sendToDetector>(F_GET_GATE_DELAY_ALL_GATES); } -bool Module::isMaster() const{ - return sendToDetector(F_GET_MASTER); -} +bool Module::isMaster() const { return sendToDetector(F_GET_MASTER); } -int Module::getChipStatusRegister() const{ +int Module::getChipStatusRegister() const { return sendToDetector(F_GET_CSR); } -void Module::setGainCaps(int caps){ +void Module::setGainCaps(int caps) { sendToDetector(F_SET_GAIN_CAPS, caps); } -int Module::getGainCaps(){ - return sendToDetector(F_GET_GAIN_CAPS); -} +int Module::getGainCaps() { return sendToDetector(F_GET_GAIN_CAPS); } // CTB / Moench Specific int Module::getNumberOfAnalogSamples() const { @@ -3209,7 +3217,6 @@ sls_detector_module Module::readSettingsFile(const std::string &fname, auto file_size = getFileSize(infile); - // eiger if (shm()->myDetectorType == EIGER) { infile.read(reinterpret_cast(myMod.dacs), @@ -3235,16 +3242,15 @@ sls_detector_module Module::readSettingsFile(const std::string &fname, // mythen3 (dacs, trimbits) else if (shm()->myDetectorType == MYTHEN3) { - int expected_size = - sizeof(int) * myMod.ndac + sizeof(int) * myMod.nchan + sizeof(myMod.reg); + int expected_size = sizeof(int) * myMod.ndac + + sizeof(int) * myMod.nchan + sizeof(myMod.reg); if (file_size != expected_size) { throw RuntimeError("The size of the settings file: " + fname + " differs from the expected size, " + std::to_string(file_size) + " instead of " + std::to_string(expected_size) + " bytes"); } - infile.read(reinterpret_cast(&myMod.reg), - sizeof(myMod.reg)); + infile.read(reinterpret_cast(&myMod.reg), sizeof(myMod.reg)); infile.read(reinterpret_cast(myMod.dacs), sizeof(int) * (myMod.ndac)); for (int i = 0; i < myMod.ndac; ++i) { diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index 445bccc40..a611ab5b6 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -343,6 +343,8 @@ class Module : public virtual slsDetectorDefs { void pulseChip(int n_pulses = 0); bool getQuad() const; void setQuad(const bool enable); + bool getDataStream(const bool left) const; + void setDataStream(const bool enable, const bool left); /************************************************** * * diff --git a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp index 0249b6460..a2b9625b3 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-eiger.cpp @@ -649,3 +649,43 @@ TEST_CASE("quad", "[.cmd]") { REQUIRE_THROWS(proxy.Call("quad", {}, -1, GET)); } } + +TEST_CASE("datastream", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::EIGER) { + auto prev_val_left = det.getDataStream(true); + auto prev_val_right = det.getDataStream(false); + // no "left" or "right" + REQUIRE_THROWS(proxy.Call("datastream", {"1"}, -1, PUT)); + { + std::ostringstream oss; + proxy.Call("datastream", {"0", "left"}, -1, PUT, oss); + REQUIRE(oss.str() == "datastream 0 left\n"); + } + { + std::ostringstream oss; + proxy.Call("datastream", {"0", "right"}, -1, PUT, oss); + REQUIRE(oss.str() == "datastream 0 right\n"); + } + { + std::ostringstream oss; + proxy.Call("datastream", {"1", "left"}, -1, PUT, oss); + REQUIRE(oss.str() == "datastream 1 left\n"); + } + { + std::ostringstream oss; + proxy.Call("datastream", {"1", "right"}, -1, PUT, oss); + REQUIRE(oss.str() == "datastream 1 right\n"); + } + for (int i = 0; i != det.size(); ++i) { + det.setDataStream(prev_val_left[i], {i}); + det.setDataStream(prev_val_right[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("datastream", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("datastream", {"1"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("datastream", {"1", "left"}, -1, PUT)); + } +} \ No newline at end of file diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index bfc3eecdb..061964010 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -224,6 +224,8 @@ enum detFuncs { F_GET_CSR, F_SET_GAIN_CAPS, F_GET_GAIN_CAPS, + F_GET_DATASTREAM, + F_SET_DATASTREAM, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -551,6 +553,8 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_LOAD_DEFAULT_PATTERN: return "F_LOAD_DEFAULT_PATTERN"; case F_GET_ALL_THRESHOLD_ENERGY: return "F_GET_ALL_THRESHOLD_ENERGY"; case F_GET_MASTER: return "F_GET_MASTER"; + case F_GET_DATASTREAM: return "F_GET_DATASTREAM"; + case F_SET_DATASTREAM: return "F_SET_DATASTREAM"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START";