diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.c b/slsDetectorServers/eigerDetectorServer/FebControl.c index 2f44d2b21..5c9ea3efc 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.c +++ b/slsDetectorServers/eigerDetectorServer/FebControl.c @@ -998,7 +998,7 @@ int Feb_Control_StartAcquisition() { int Feb_Control_StopAcquisition() { return Feb_Control_Reset(); } -int Feb_Control_SoftwareTrigger() { +int Feb_Control_SoftwareTrigger(int block) { if (Feb_Control_activated) { // read exp toggle value unsigned int value = 0; @@ -1063,10 +1063,12 @@ int Feb_Control_SoftwareTrigger() { } // wait for toggle for exposure to be done - while (toggle == prev_toggle) { - usleep(5000); - toggle = ((value & FEB_REG_STATUS_EXP_TGL_MSK) >> - FEB_REG_STATUS_EXP_TGL_OFST); + if (block) { + while (toggle == prev_toggle) { + usleep(5000); + toggle = ((value & FEB_REG_STATUS_EXP_TGL_MSK) >> + FEB_REG_STATUS_EXP_TGL_OFST); + } } } return 1; diff --git a/slsDetectorServers/eigerDetectorServer/FebControl.h b/slsDetectorServers/eigerDetectorServer/FebControl.h index db8819c94..4c48d6686 100644 --- a/slsDetectorServers/eigerDetectorServer/FebControl.h +++ b/slsDetectorServers/eigerDetectorServer/FebControl.h @@ -55,7 +55,7 @@ int Feb_Control_PrepareForAcquisition(); void Feb_Control_PrintAcquisitionSetup(); int Feb_Control_StartAcquisition(); int Feb_Control_StopAcquisition(); -int Feb_Control_SoftwareTrigger(); +int Feb_Control_SoftwareTrigger(int block); // parameters int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); diff --git a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c index e06df6040..6631f0aa6 100644 --- a/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/eigerDetectorServer/slsDetectorFunctionList.c @@ -2404,12 +2404,12 @@ int stopStateMachine() { #endif } -int softwareTrigger() { +int softwareTrigger(int block) { #ifdef VIRTUAL return OK; #else sharedMemory_lockLocalLink(); - if (!Feb_Control_SoftwareTrigger()) { + if (!Feb_Control_SoftwareTrigger(block)) { sharedMemory_unlockLocalLink(); return FAIL; } diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 65b5d7fb1..e1670ea48 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -25,7 +25,7 @@ #include "blackfin.h" #endif -#if defined(MYTHEN3D) +#if defined(MYTHEN3D) #include "mythen3.h" #endif @@ -360,7 +360,7 @@ int isMaster(); int setGainCaps(int caps); int getGainCaps(); int setChipStatusRegister(int csr); -int setDACS(int* dacs); +int setDACS(int *dacs); #endif #if defined(GOTTHARDD) || defined(MYTHEN3D) void setExtSignal(int signalIndex, enum externalSignalFlag mode); @@ -576,9 +576,12 @@ int startStateMachine(); void *start_timer(void *arg); #endif int stopStateMachine(); -#if defined(EIGERD) || defined(MYTHEN3D) +#ifdef MYTHEN3D int softwareTrigger(); #endif +#ifdef EIGERD +int softwareTrigger(int block); +#endif #if defined(EIGERD) || defined(MYTHEN3D) int startReadOut(); #endif diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 362c450d0..64e62f3bd 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -642,9 +642,9 @@ int set_timing_mode(int file_des) { } // get retval = getTiming(); - #ifndef MYTHEN3D +#ifndef MYTHEN3D validate((int)arg, (int)retval, "set timing mode", DEC); - #endif +#endif LOG(logDEBUG1, ("Timing Mode: %d\n", retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); @@ -1552,7 +1552,7 @@ int set_module(int file_des) { // check index #if !(defined(EIGERD) || defined(MYTHEN3D)) -//TODO! Check if this is used for any detector + // TODO! Check if this is used for any detector switch (module.reg) { #ifdef JUNGFRAUD case DYNAMICGAIN: @@ -4163,16 +4163,29 @@ int check_version(int file_des) { int software_trigger(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, ("Software Trigger (block: %d\n", arg)); - LOG(logDEBUG1, ("Software Trigger\n")); #if !defined(EIGERD) && !defined(MYTHEN3D) functionNotImplemented(); #else + if (arg && myDetectorType == MYTHEN3) { + ret = FAIL; + strcpy(mess, "Blocking trigger not implemented for Mythen3. Please use non blocking trigger.\n"); + LOG(logERROR, (mess)); + } // only set - if (Server_VerifyLock() == OK) { + else if (Server_VerifyLock() == OK) { +#ifdef MYTHEN3 ret = softwareTrigger(); +#else + ret = softwareTrigger(arg); +#endif if (ret == FAIL) { - sprintf(mess, "Could not send software trigger\n"); + strcpy(mess, "Could not send software trigger\n"); LOG(logERROR, (mess)); } LOG(logDEBUG1, ("Software trigger successful\n")); @@ -7576,21 +7589,23 @@ int set_pattern(int file_des) { patternParameters *pat = malloc(sizeof(patternParameters)); memset(pat, 0, sizeof(patternParameters)); - // ignoring endianness for eiger + // ignoring endianness for eiger if (receiveData(file_des, pat, sizeof(patternParameters), INT32) < 0) { if (pat != NULL) free(pat); return printSocketReadError(); } - + if (Server_VerifyLock() == OK) { LOG(logINFO, ("Setting Pattern from structure\n")); LOG(logINFO, - ("Setting Pattern Word (printing every 10 words that are not 0\n")); - /****************************************************************************************************************/ - /* I SUGGEST TO VALIDATE THE VALUES HERE AND THEN WRITE THE PATTERN IN A SEPARATE FUNCTION WHICH COULD BE REUSED*/ - /* added loadPattern.c/h - the same func could be reused also in readDefaultPattern */ - /***************************************************************************************************************/ + ("Setting Pattern Word (printing every 10 words that are not 0\n")); + /****************************************************************************************************************/ + /* I SUGGEST TO VALIDATE THE VALUES HERE AND THEN WRITE THE PATTERN IN A + * SEPARATE FUNCTION WHICH COULD BE REUSED*/ + /* added loadPattern.c/h - the same func could be reused also in + * readDefaultPattern */ + /***************************************************************************************************************/ for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) { if ((i % 10 == 0) && pat->word[i] != 0) { @@ -7664,7 +7679,7 @@ int set_pattern(int file_des) { } } } - /******* DOWN TO HERE ***********/ + /******* DOWN TO HERE ***********/ } if (pat != NULL) free(pat); @@ -8372,7 +8387,7 @@ int get_all_threshold_energy(int file_des) { return Server_SendResult(file_des, INT32, retvals, sizeof(retvals)); } -int get_master(int file_des){ +int get_master(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); int retval = -1; @@ -8387,7 +8402,7 @@ int get_master(int file_des){ return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } -int get_csr(int file_des){ +int get_csr(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); int retval = -1; @@ -8402,7 +8417,7 @@ int get_csr(int file_des){ return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } -int set_gain_caps(int file_des){ +int set_gain_caps(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); int arg = 0; @@ -8418,14 +8433,14 @@ int set_gain_caps(int file_des){ #else if (Server_VerifyLock() == OK) { setGainCaps(arg); - retval = getChipStatusRegister(); //TODO! fix + retval = getChipStatusRegister(); // TODO! fix LOG(logDEBUG1, ("gain caps retval: %u\n", retval)); } #endif return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } -int get_gain_caps(int file_des){ +int get_gain_caps(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); // int arg = 0; diff --git a/slsDetectorSoftware/include/sls/Detector.h b/slsDetectorSoftware/include/sls/Detector.h index ca93b617b..1d08dde69 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -520,8 +520,10 @@ class Detector { * numbers for different modules.*/ void setNextFrameNumber(uint64_t value, Positions pos = {}); - /** [Eiger][Mythen3] Sends an internal software trigger to the detector */ - void sendSoftwareTrigger(Positions pos = {}); + /** [Eiger][Mythen3] Sends an internal software trigger to the detector + * block true if command blocks till frames are sent out from that trigger + */ + void sendSoftwareTrigger(const bool block = false, Positions pos = {}); Result getScan(Positions pos = {}) const; @@ -1308,8 +1310,7 @@ class Detector { Result getMaster(Positions pos = {}) const; - - //TODO! check if we really want to expose this !!!!! + // TODO! check if we really want to expose this !!!!! Result getChipStatusRegister(Positions pos = {}) const; void setGainCaps(int caps, Positions pos = {}); diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 183c94490..a23052b00 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1193,6 +1193,41 @@ std::string CmdProxy::Scan(int action) { return os.str(); } +std::string CmdProxy::Trigger(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + if (cmd == "trigger") { + os << "[Eiger][Mythen3] Sends software trigger signal to detector"; + } else if (cmd == "blockingtrigger") { + os << "[Eiger] Sends software trigger signal to detector and " + "blocks till " + "the frames are sent out for that trigger."; + } else { + throw sls::RuntimeError("unknown command " + cmd); + } + os << '\n'; + } else if (action == slsDetectorDefs::GET_ACTION) { + throw sls::RuntimeError("Cannot get"); + } else if (action == slsDetectorDefs::PUT_ACTION) { + if (det_id != -1) { + throw sls::RuntimeError("Cannot execute this at module level"); + } + if (!args.empty()) { + WrongNumberOfParameters(0); + } + bool block = false; + if (cmd == "blockingtrigger") { + block = true; + } + det->sendSoftwareTrigger(block); + os << "successful\n"; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + /* Network Configuration (Detector<->Receiver) */ std::string CmdProxy::UDPDestinationIP(int action) { @@ -1981,12 +2016,12 @@ std::string CmdProxy::GateDelay(int action) { return os.str(); } - -std::string CmdProxy::GainCaps(int action){ +std::string CmdProxy::GainCaps(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[cap1, cap2, ...]\n\t[Mythen3] gain, options: C10pre, C15sh, C30sh, C50sh, C225ACsh, C15pre" + os << "[cap1, cap2, ...]\n\t[Mythen3] gain, options: C10pre, C15sh, " + "C30sh, C50sh, C225ACsh, C15pre" << '\n'; } else if (action == defs::GET_ACTION) { if (!args.empty()) @@ -1994,22 +2029,22 @@ std::string CmdProxy::GainCaps(int action){ auto tmp = det->getGainCaps(); sls::Result csr; - for (auto val : tmp){ + for (auto val : tmp) { if (val) csr.push_back(static_cast(val)); } - + os << OutString(csr) << '\n'; } else if (action == defs::PUT_ACTION) { if (args.size() < 1) { WrongNumberOfParameters(1); } int caps = 0; - for (const auto& arg:args){ + for (const auto &arg : args) { if (arg != "0") caps |= sls::StringTo(arg); } - + det->setGainCaps(caps); os << OutString(args) << '\n'; } else { diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index da5d38b7e..f0d3e41ff 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; @@ -839,7 +838,7 @@ class CmdProxy { {"rx_framescaught", &CmdProxy::rx_framescaught}, {"rx_missingpackets", &CmdProxy::rx_missingpackets}, {"nextframenumber", &CmdProxy::nextframenumber}, - {"trigger", &CmdProxy::trigger}, + {"trigger", &CmdProxy::Trigger}, {"scan", &CmdProxy::Scan}, {"scanerrmsg", &CmdProxy::scanerrmsg}, @@ -900,6 +899,7 @@ class CmdProxy { {"rx_zmqhwm", &CmdProxy::rx_zmqhwm}, /* Eiger Specific */ + {"blockingtrigger", &CmdProxy::Trigger}, {"subexptime", &CmdProxy::subexptime}, {"subdeadtime", &CmdProxy::subdeadtime}, {"overflow", &CmdProxy::overflow}, @@ -1094,6 +1094,7 @@ class CmdProxy { std::string ReceiverStatus(int action); std::string DetectorStatus(int action); std::string Scan(int action); + std::string Trigger(int action); /* Network Configuration (Detector<->Receiver) */ std::string UDPDestinationIP(int action); std::string UDPDestinationIP2(int action); @@ -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."); @@ -1460,10 +1461,6 @@ class CmdProxy { "Stopping acquisition might result in " "different frame numbers for different modules."); - EXECUTE_SET_COMMAND( - trigger, sendSoftwareTrigger, - "\n\t[Eiger][Mythen3] Sends software trigger signal to detector."); - GET_COMMAND(scanerrmsg, getScanErrorMessage, "\n\tGets Scan error message if scan ended in error for non " "blocking acquisitions."); diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index 4cc64e6bc..b0cc2d9d9 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); @@ -724,8 +725,8 @@ void Detector::setNextFrameNumber(uint64_t value, Positions pos) { pimpl->Parallel(&Module::setNextFrameNumber, pos, value); } -void Detector::sendSoftwareTrigger(Positions pos) { - pimpl->Parallel(&Module::sendSoftwareTrigger, pos); +void Detector::sendSoftwareTrigger(const bool block, Positions pos) { + pimpl->Parallel(&Module::sendSoftwareTrigger, pos, false); } Result Detector::getScan(Positions pos) const { @@ -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); } @@ -1611,23 +1614,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..5a7a46b21 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(); } @@ -773,7 +776,9 @@ void Module::setNextFrameNumber(uint64_t value) { sendToDetector(F_SET_NEXT_FRAME_NUMBER, value, nullptr); } -void Module::sendSoftwareTrigger() { sendToDetectorStop(F_SOFTWARE_TRIGGER); } +void Module::sendSoftwareTrigger(const bool block) { + sendToDetectorStop(F_SOFTWARE_TRIGGER, static_cast(block), nullptr); +} defs::scanParameters Module::getScan() const { return sendToDetector(F_GET_SCAN); @@ -1994,21 +1999,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 +3210,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 +3235,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..6462ffac2 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -185,7 +185,7 @@ class Module : public virtual slsDetectorDefs { std::vector getNumMissingPackets() const; uint64_t getNextFrameNumber() const; void setNextFrameNumber(uint64_t value); - void sendSoftwareTrigger(); + void sendSoftwareTrigger(const bool block); defs::scanParameters getScan() const; void setScan(const defs::scanParameters t); std::string getScanErrorMessage() const; diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index a28fedde2..c9ca73ea2 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -1446,6 +1446,45 @@ TEST_CASE("trigger", "[.cmd]") { } } +TEST_CASE("blockingtrigger", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + REQUIRE_THROWS(proxy.Call("blockingtrigger", {}, -1, GET)); + auto det_type = det.getDetectorType().squash(); + if (det_type != defs::EIGER) { + REQUIRE_THROWS(proxy.Call("blockingtrigger", {}, -1, PUT)); + } else if (det_type == defs::EIGER) { + auto prev_timing = + det.getTimingMode().tsquash("inconsistent timing mode in test"); + auto prev_frames = + det.getNumberOfFrames().tsquash("inconsistent #frames in test"); + auto prev_exptime = + det.getExptime().tsquash("inconsistent exptime in test"); + auto prev_period = + det.getPeriod().tsquash("inconsistent period in test"); + det.setTimingMode(defs::TRIGGER_EXPOSURE); + det.setNumberOfFrames(1); + det.setExptime(std::chrono::microseconds(200)); + det.setPeriod(std::chrono::milliseconds(1)); + auto nextframenumber = + det.getNextFrameNumber().tsquash("inconsistent frame nr in test"); + det.startDetector(); + { + std::ostringstream oss; + proxy.Call("blockingtrigger", {}, -1, PUT, oss); + REQUIRE(oss.str() == "blockingtrigger successful\n"); + } + auto currentfnum = + det.getNextFrameNumber().tsquash("inconsistent frame nr in test"); + REQUIRE(nextframenumber + 1 == currentfnum); + det.stopDetector(); + det.setTimingMode(prev_timing); + det.setNumberOfFrames(prev_frames); + det.setExptime(prev_exptime); + det.setPeriod(prev_period); + } +} + TEST_CASE("clearbusy", "[.cmd]") { Detector det; CmdProxy proxy(&det);