This commit is contained in:
maliakal_d 2021-06-04 12:30:59 +02:00
parent 215454d7cc
commit 0afe093afc
12 changed files with 186 additions and 93 deletions

View File

@ -998,7 +998,7 @@ int Feb_Control_StartAcquisition() {
int Feb_Control_StopAcquisition() { return Feb_Control_Reset(); } int Feb_Control_StopAcquisition() { return Feb_Control_Reset(); }
int Feb_Control_SoftwareTrigger() { int Feb_Control_SoftwareTrigger(int block) {
if (Feb_Control_activated) { if (Feb_Control_activated) {
// read exp toggle value // read exp toggle value
unsigned int value = 0; unsigned int value = 0;
@ -1063,10 +1063,12 @@ int Feb_Control_SoftwareTrigger() {
} }
// wait for toggle for exposure to be done // wait for toggle for exposure to be done
while (toggle == prev_toggle) { if (block) {
usleep(5000); while (toggle == prev_toggle) {
toggle = ((value & FEB_REG_STATUS_EXP_TGL_MSK) >> usleep(5000);
FEB_REG_STATUS_EXP_TGL_OFST); toggle = ((value & FEB_REG_STATUS_EXP_TGL_MSK) >>
FEB_REG_STATUS_EXP_TGL_OFST);
}
} }
} }
return 1; return 1;

View File

@ -55,7 +55,7 @@ int Feb_Control_PrepareForAcquisition();
void Feb_Control_PrintAcquisitionSetup(); void Feb_Control_PrintAcquisitionSetup();
int Feb_Control_StartAcquisition(); int Feb_Control_StartAcquisition();
int Feb_Control_StopAcquisition(); int Feb_Control_StopAcquisition();
int Feb_Control_SoftwareTrigger(); int Feb_Control_SoftwareTrigger(int block);
// parameters // parameters
int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo); int Feb_Control_SetDynamicRange(unsigned int four_eight_sixteen_or_thirtytwo);

View File

@ -2404,12 +2404,12 @@ int stopStateMachine() {
#endif #endif
} }
int softwareTrigger() { int softwareTrigger(int block) {
#ifdef VIRTUAL #ifdef VIRTUAL
return OK; return OK;
#else #else
sharedMemory_lockLocalLink(); sharedMemory_lockLocalLink();
if (!Feb_Control_SoftwareTrigger()) { if (!Feb_Control_SoftwareTrigger(block)) {
sharedMemory_unlockLocalLink(); sharedMemory_unlockLocalLink();
return FAIL; return FAIL;
} }

View File

@ -25,7 +25,7 @@
#include "blackfin.h" #include "blackfin.h"
#endif #endif
#if defined(MYTHEN3D) #if defined(MYTHEN3D)
#include "mythen3.h" #include "mythen3.h"
#endif #endif
@ -360,7 +360,7 @@ int isMaster();
int setGainCaps(int caps); int setGainCaps(int caps);
int getGainCaps(); int getGainCaps();
int setChipStatusRegister(int csr); int setChipStatusRegister(int csr);
int setDACS(int* dacs); int setDACS(int *dacs);
#endif #endif
#if defined(GOTTHARDD) || defined(MYTHEN3D) #if defined(GOTTHARDD) || defined(MYTHEN3D)
void setExtSignal(int signalIndex, enum externalSignalFlag mode); void setExtSignal(int signalIndex, enum externalSignalFlag mode);
@ -576,9 +576,12 @@ int startStateMachine();
void *start_timer(void *arg); void *start_timer(void *arg);
#endif #endif
int stopStateMachine(); int stopStateMachine();
#if defined(EIGERD) || defined(MYTHEN3D) #ifdef MYTHEN3D
int softwareTrigger(); int softwareTrigger();
#endif #endif
#ifdef EIGERD
int softwareTrigger(int block);
#endif
#if defined(EIGERD) || defined(MYTHEN3D) #if defined(EIGERD) || defined(MYTHEN3D)
int startReadOut(); int startReadOut();
#endif #endif

View File

@ -642,9 +642,9 @@ int set_timing_mode(int file_des) {
} }
// get // get
retval = getTiming(); retval = getTiming();
#ifndef MYTHEN3D #ifndef MYTHEN3D
validate((int)arg, (int)retval, "set timing mode", DEC); validate((int)arg, (int)retval, "set timing mode", DEC);
#endif #endif
LOG(logDEBUG1, ("Timing Mode: %d\n", retval)); LOG(logDEBUG1, ("Timing Mode: %d\n", retval));
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
@ -1552,7 +1552,7 @@ int set_module(int file_des) {
// check index // check index
#if !(defined(EIGERD) || defined(MYTHEN3D)) #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) { switch (module.reg) {
#ifdef JUNGFRAUD #ifdef JUNGFRAUD
case DYNAMICGAIN: case DYNAMICGAIN:
@ -4163,16 +4163,29 @@ int check_version(int file_des) {
int software_trigger(int file_des) { int software_trigger(int file_des) {
ret = OK; ret = OK;
memset(mess, 0, sizeof(mess)); 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) #if !defined(EIGERD) && !defined(MYTHEN3D)
functionNotImplemented(); functionNotImplemented();
#else #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 // only set
if (Server_VerifyLock() == OK) { else if (Server_VerifyLock() == OK) {
#ifdef MYTHEN3
ret = softwareTrigger(); ret = softwareTrigger();
#else
ret = softwareTrigger(arg);
#endif
if (ret == FAIL) { if (ret == FAIL) {
sprintf(mess, "Could not send software trigger\n"); strcpy(mess, "Could not send software trigger\n");
LOG(logERROR, (mess)); LOG(logERROR, (mess));
} }
LOG(logDEBUG1, ("Software trigger successful\n")); LOG(logDEBUG1, ("Software trigger successful\n"));
@ -7576,21 +7589,23 @@ int set_pattern(int file_des) {
patternParameters *pat = malloc(sizeof(patternParameters)); patternParameters *pat = malloc(sizeof(patternParameters));
memset(pat, 0, 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 (receiveData(file_des, pat, sizeof(patternParameters), INT32) < 0) {
if (pat != NULL) if (pat != NULL)
free(pat); free(pat);
return printSocketReadError(); return printSocketReadError();
} }
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
LOG(logINFO, ("Setting Pattern from structure\n")); LOG(logINFO, ("Setting Pattern from structure\n"));
LOG(logINFO, LOG(logINFO,
("Setting Pattern Word (printing every 10 words that are not 0\n")); ("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*/ /* I SUGGEST TO VALIDATE THE VALUES HERE AND THEN WRITE THE PATTERN IN A
/* added loadPattern.c/h - the same func could be reused also in readDefaultPattern */ * 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) { for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) {
if ((i % 10 == 0) && pat->word[i] != 0) { 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) if (pat != NULL)
free(pat); free(pat);
@ -8372,7 +8387,7 @@ int get_all_threshold_energy(int file_des) {
return Server_SendResult(file_des, INT32, retvals, sizeof(retvals)); return Server_SendResult(file_des, INT32, retvals, sizeof(retvals));
} }
int get_master(int file_des){ int get_master(int file_des) {
ret = OK; ret = OK;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
int retval = -1; int retval = -1;
@ -8387,7 +8402,7 @@ int get_master(int file_des){
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); return Server_SendResult(file_des, INT32, &retval, sizeof(retval));
} }
int get_csr(int file_des){ int get_csr(int file_des) {
ret = OK; ret = OK;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
int retval = -1; int retval = -1;
@ -8402,7 +8417,7 @@ int get_csr(int file_des){
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); 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; ret = OK;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
int arg = 0; int arg = 0;
@ -8418,14 +8433,14 @@ int set_gain_caps(int file_des){
#else #else
if (Server_VerifyLock() == OK) { if (Server_VerifyLock() == OK) {
setGainCaps(arg); setGainCaps(arg);
retval = getChipStatusRegister(); //TODO! fix retval = getChipStatusRegister(); // TODO! fix
LOG(logDEBUG1, ("gain caps retval: %u\n", retval)); LOG(logDEBUG1, ("gain caps retval: %u\n", retval));
} }
#endif #endif
return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); 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; ret = OK;
memset(mess, 0, sizeof(mess)); memset(mess, 0, sizeof(mess));
// int arg = 0; // int arg = 0;

View File

@ -520,8 +520,10 @@ class Detector {
* numbers for different modules.*/ * numbers for different modules.*/
void setNextFrameNumber(uint64_t value, Positions pos = {}); void setNextFrameNumber(uint64_t value, Positions pos = {});
/** [Eiger][Mythen3] Sends an internal software trigger to the detector */ /** [Eiger][Mythen3] Sends an internal software trigger to the detector
void sendSoftwareTrigger(Positions pos = {}); * block true if command blocks till frames are sent out from that trigger
*/
void sendSoftwareTrigger(const bool block = false, Positions pos = {});
Result<defs::scanParameters> getScan(Positions pos = {}) const; Result<defs::scanParameters> getScan(Positions pos = {}) const;
@ -1308,8 +1310,7 @@ class Detector {
Result<bool> getMaster(Positions pos = {}) const; Result<bool> getMaster(Positions pos = {}) const;
// TODO! check if we really want to expose this !!!!!
//TODO! check if we really want to expose this !!!!!
Result<int> getChipStatusRegister(Positions pos = {}) const; Result<int> getChipStatusRegister(Positions pos = {}) const;
void setGainCaps(int caps, Positions pos = {}); void setGainCaps(int caps, Positions pos = {});

View File

@ -1193,6 +1193,41 @@ std::string CmdProxy::Scan(int action) {
return os.str(); 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) */ /* Network Configuration (Detector<->Receiver) */
std::string CmdProxy::UDPDestinationIP(int action) { std::string CmdProxy::UDPDestinationIP(int action) {
@ -1981,12 +2016,12 @@ std::string CmdProxy::GateDelay(int action) {
return os.str(); return os.str();
} }
std::string CmdProxy::GainCaps(int action) {
std::string CmdProxy::GainCaps(int action){
std::ostringstream os; std::ostringstream os;
os << cmd << ' '; os << cmd << ' ';
if (action == defs::HELP_ACTION) { 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'; << '\n';
} else if (action == defs::GET_ACTION) { } else if (action == defs::GET_ACTION) {
if (!args.empty()) if (!args.empty())
@ -1994,22 +2029,22 @@ std::string CmdProxy::GainCaps(int action){
auto tmp = det->getGainCaps(); auto tmp = det->getGainCaps();
sls::Result<defs::M3_GainCaps> csr; sls::Result<defs::M3_GainCaps> csr;
for (auto val : tmp){ for (auto val : tmp) {
if (val) if (val)
csr.push_back(static_cast<defs::M3_GainCaps>(val)); csr.push_back(static_cast<defs::M3_GainCaps>(val));
} }
os << OutString(csr) << '\n'; os << OutString(csr) << '\n';
} else if (action == defs::PUT_ACTION) { } else if (action == defs::PUT_ACTION) {
if (args.size() < 1) { if (args.size() < 1) {
WrongNumberOfParameters(1); WrongNumberOfParameters(1);
} }
int caps = 0; int caps = 0;
for (const auto& arg:args){ for (const auto &arg : args) {
if (arg != "0") if (arg != "0")
caps |= sls::StringTo<defs::M3_GainCaps>(arg); caps |= sls::StringTo<defs::M3_GainCaps>(arg);
} }
det->setGainCaps(caps); det->setGainCaps(caps);
os << OutString(args) << '\n'; os << OutString(args) << '\n';
} else { } else {

View File

@ -571,7 +571,6 @@ class CmdProxy {
return ToString(value, unit); return ToString(value, unit);
} }
using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>; using FunctionMap = std::map<std::string, std::string (CmdProxy::*)(int)>;
using StringMap = std::map<std::string, std::string>; using StringMap = std::map<std::string, std::string>;
@ -839,7 +838,7 @@ class CmdProxy {
{"rx_framescaught", &CmdProxy::rx_framescaught}, {"rx_framescaught", &CmdProxy::rx_framescaught},
{"rx_missingpackets", &CmdProxy::rx_missingpackets}, {"rx_missingpackets", &CmdProxy::rx_missingpackets},
{"nextframenumber", &CmdProxy::nextframenumber}, {"nextframenumber", &CmdProxy::nextframenumber},
{"trigger", &CmdProxy::trigger}, {"trigger", &CmdProxy::Trigger},
{"scan", &CmdProxy::Scan}, {"scan", &CmdProxy::Scan},
{"scanerrmsg", &CmdProxy::scanerrmsg}, {"scanerrmsg", &CmdProxy::scanerrmsg},
@ -900,6 +899,7 @@ class CmdProxy {
{"rx_zmqhwm", &CmdProxy::rx_zmqhwm}, {"rx_zmqhwm", &CmdProxy::rx_zmqhwm},
/* Eiger Specific */ /* Eiger Specific */
{"blockingtrigger", &CmdProxy::Trigger},
{"subexptime", &CmdProxy::subexptime}, {"subexptime", &CmdProxy::subexptime},
{"subdeadtime", &CmdProxy::subdeadtime}, {"subdeadtime", &CmdProxy::subdeadtime},
{"overflow", &CmdProxy::overflow}, {"overflow", &CmdProxy::overflow},
@ -1094,6 +1094,7 @@ class CmdProxy {
std::string ReceiverStatus(int action); std::string ReceiverStatus(int action);
std::string DetectorStatus(int action); std::string DetectorStatus(int action);
std::string Scan(int action); std::string Scan(int action);
std::string Trigger(int action);
/* Network Configuration (Detector<->Receiver) */ /* Network Configuration (Detector<->Receiver) */
std::string UDPDestinationIP(int action); std::string UDPDestinationIP(int action);
std::string UDPDestinationIP2(int action); std::string UDPDestinationIP2(int action);
@ -1445,8 +1446,8 @@ class CmdProxy {
"and automatically returns to idle at the end of readout."); "and automatically returns to idle at the end of readout.");
EXECUTE_SET_COMMAND(stop, stopDetector, EXECUTE_SET_COMMAND(stop, stopDetector,
"\n\tAbort detector acquisition. Status changes " "\n\tAbort detector acquisition. Status changes "
"to IDLE or STOPPED. Goes to stop server."); "to IDLE or STOPPED. Goes to stop server.");
GET_COMMAND(rx_framescaught, getFramesCaught, GET_COMMAND(rx_framescaught, getFramesCaught,
"\n\tNumber of frames caught by receiver."); "\n\tNumber of frames caught by receiver.");
@ -1460,10 +1461,6 @@ class CmdProxy {
"Stopping acquisition might result in " "Stopping acquisition might result in "
"different frame numbers for different modules."); "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, GET_COMMAND(scanerrmsg, getScanErrorMessage,
"\n\tGets Scan error message if scan ended in error for non " "\n\tGets Scan error message if scan ended in error for non "
"blocking acquisitions."); "blocking acquisitions.");

View File

@ -675,11 +675,11 @@ void Detector::stopReceiver() { pimpl->Parallel(&Module::stopReceiver, {}); }
void Detector::startDetector() { void Detector::startDetector() {
auto detector_type = getDetectorType().squash(); auto detector_type = getDetectorType().squash();
if (detector_type == defs::MYTHEN3 && size() > 1){ if (detector_type == defs::MYTHEN3 && size() > 1) {
auto is_master = getMaster(); auto is_master = getMaster();
std::vector<int> master; std::vector<int> master;
std::vector<int> slaves; std::vector<int> slaves;
for(int i=0; i<size(); ++i){ for (int i = 0; i < size(); ++i) {
if (is_master[i]) if (is_master[i])
master.push_back(i); master.push_back(i);
else else
@ -687,17 +687,18 @@ void Detector::startDetector() {
} }
pimpl->Parallel(&Module::startAcquisition, slaves); pimpl->Parallel(&Module::startAcquisition, slaves);
pimpl->Parallel(&Module::startAcquisition, master); pimpl->Parallel(&Module::startAcquisition, master);
}else{ } else {
pimpl->Parallel(&Module::startAcquisition, {}); pimpl->Parallel(&Module::startAcquisition, {});
} }
} }
void Detector::startDetectorReadout() { void Detector::startDetectorReadout() {
pimpl->Parallel(&Module::startReadout, {}); 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<defs::runStatus> Detector::getDetectorStatus(Positions pos) const { Result<defs::runStatus> Detector::getDetectorStatus(Positions pos) const {
return pimpl->Parallel(&Module::getRunStatus, pos); return pimpl->Parallel(&Module::getRunStatus, pos);
@ -724,8 +725,8 @@ void Detector::setNextFrameNumber(uint64_t value, Positions pos) {
pimpl->Parallel(&Module::setNextFrameNumber, pos, value); pimpl->Parallel(&Module::setNextFrameNumber, pos, value);
} }
void Detector::sendSoftwareTrigger(Positions pos) { void Detector::sendSoftwareTrigger(const bool block, Positions pos) {
pimpl->Parallel(&Module::sendSoftwareTrigger, pos); pimpl->Parallel(&Module::sendSoftwareTrigger, pos, false);
} }
Result<defs::scanParameters> Detector::getScan(Positions pos) const { Result<defs::scanParameters> Detector::getScan(Positions pos) const {
@ -733,8 +734,10 @@ Result<defs::scanParameters> Detector::getScan(Positions pos) const {
} }
void Detector::setScan(const defs::scanParameters t) { void Detector::setScan(const defs::scanParameters t) {
if(getDetectorType().squash() == defs::MYTHEN3 && size()>1 && t.enable != 0){ if (getDetectorType().squash() == defs::MYTHEN3 && size() > 1 &&
throw DetectorError("Scan is only allowed for single module Mythen 3 because of synchronization"); t.enable != 0) {
throw DetectorError("Scan is only allowed for single module Mythen 3 "
"because of synchronization");
} }
pimpl->Parallel(&Module::setScan, {}, t); pimpl->Parallel(&Module::setScan, {}, t);
} }
@ -1611,23 +1614,22 @@ Detector::getGateDelayForAllGates(Positions pos) const {
return pimpl->Parallel(&Module::getGateDelayForAllGates, pos); return pimpl->Parallel(&Module::getGateDelayForAllGates, pos);
} }
Result<bool> Detector::getMaster(Positions pos) const{ Result<bool> Detector::getMaster(Positions pos) const {
return pimpl->Parallel(&Module::isMaster, pos); return pimpl->Parallel(&Module::isMaster, pos);
} }
Result<int> Detector::getChipStatusRegister(Positions pos) const{ Result<int> Detector::getChipStatusRegister(Positions pos) const {
return pimpl->Parallel(&Module::getChipStatusRegister, pos); 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); return pimpl->Parallel(&Module::setGainCaps, pos, caps);
} }
Result<int> Detector::getGainCaps(Positions pos){ Result<int> Detector::getGainCaps(Positions pos) {
return pimpl->Parallel(&Module::getGainCaps, pos); return pimpl->Parallel(&Module::getGainCaps, pos);
} }
// CTB/ Moench Specific // CTB/ Moench Specific
Result<int> Detector::getNumberOfAnalogSamples(Positions pos) const { Result<int> Detector::getNumberOfAnalogSamples(Positions pos) const {

View File

@ -352,37 +352,39 @@ void Module::setAllThresholdEnergy(std::array<int, 3> e_eV,
std::copy(e_eV.begin(), e_eV.end(), myMod.eV); std::copy(e_eV.begin(), e_eV.end(), myMod.eV);
LOG(logDEBUG) << "ev:" << ToString(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; bool out_of_range = false;
for(int i = 0; i!=myMod.nchan; ++i){ for (int i = 0; i != myMod.nchan; ++i) {
if (myMod.chanregs[i]<0){ if (myMod.chanregs[i] < 0) {
myMod.chanregs[i] = 0; myMod.chanregs[i] = 0;
out_of_range = true; out_of_range = true;
}else if(myMod.chanregs[i]>63){ } else if (myMod.chanregs[i] > 63) {
myMod.chanregs[i]=63; myMod.chanregs[i] = 63;
out_of_range = true; out_of_range = true;
} }
} }
if (out_of_range){ if (out_of_range) {
LOG(logWARNING) << "Some trimbits were out of range after interpolation, these have been replaced with 0 or 63."; 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; out_of_range = false;
for (auto dac : {M_VTRIM,M_VTH1,M_VTH2, M_VTH3}){ for (auto dac : {M_VTRIM, M_VTH1, M_VTH2, M_VTH3}) {
if (myMod.dacs[dac] < 600){ if (myMod.dacs[dac] < 600) {
myMod.dacs[dac] = 600; myMod.dacs[dac] = 600;
out_of_range = true; out_of_range = true;
}else if(myMod.dacs[dac] > 2400){ } else if (myMod.dacs[dac] > 2400) {
myMod.dacs[dac] = 2400; myMod.dacs[dac] = 2400;
out_of_range = true; out_of_range = true;
} }
} }
if (out_of_range){ if (out_of_range) {
LOG(logWARNING) << "Some dacs were out of range after interpolation, these have been replaced with 600 or 2400."; LOG(logWARNING) << "Some dacs were out of range after interpolation, "
"these have been replaced with 600 or 2400.";
} }
setModule(myMod, trimbits); setModule(myMod, trimbits);
if (getSettings() != isettings) { if (getSettings() != isettings) {
throw RuntimeError("setThresholdEnergyAndSettings: Could not set " throw RuntimeError("setThresholdEnergyAndSettings: Could not set "
@ -412,7 +414,8 @@ void Module::loadSettingsFile(const std::string &fname) {
if (shm()->myDetectorType == MYTHEN3) { if (shm()->myDetectorType == MYTHEN3) {
serialNumberWidth = 4; 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) ostfn << ".sn" << std::setfill('0') << std::setw(serialNumberWidth)
<< std::dec << getSerialNumber(); << std::dec << getSerialNumber();
} }
@ -773,7 +776,9 @@ void Module::setNextFrameNumber(uint64_t value) {
sendToDetector(F_SET_NEXT_FRAME_NUMBER, value, nullptr); 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<int>(block), nullptr);
}
defs::scanParameters Module::getScan() const { defs::scanParameters Module::getScan() const {
return sendToDetector<defs::scanParameters>(F_GET_SCAN); return sendToDetector<defs::scanParameters>(F_GET_SCAN);
@ -1994,21 +1999,17 @@ std::array<time::ns, 3> Module::getGateDelayForAllGates() const {
return sendToDetector<std::array<time::ns, 3>>(F_GET_GATE_DELAY_ALL_GATES); return sendToDetector<std::array<time::ns, 3>>(F_GET_GATE_DELAY_ALL_GATES);
} }
bool Module::isMaster() const{ bool Module::isMaster() const { return sendToDetector<int>(F_GET_MASTER); }
return sendToDetector<int>(F_GET_MASTER);
}
int Module::getChipStatusRegister() const{ int Module::getChipStatusRegister() const {
return sendToDetector<int>(F_GET_CSR); return sendToDetector<int>(F_GET_CSR);
} }
void Module::setGainCaps(int caps){ void Module::setGainCaps(int caps) {
sendToDetector<int>(F_SET_GAIN_CAPS, caps); sendToDetector<int>(F_SET_GAIN_CAPS, caps);
} }
int Module::getGainCaps(){ int Module::getGainCaps() { return sendToDetector<int>(F_GET_GAIN_CAPS); }
return sendToDetector<int>(F_GET_GAIN_CAPS);
}
// CTB / Moench Specific // CTB / Moench Specific
int Module::getNumberOfAnalogSamples() const { int Module::getNumberOfAnalogSamples() const {
@ -3209,7 +3210,6 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
auto file_size = getFileSize(infile); auto file_size = getFileSize(infile);
// eiger // eiger
if (shm()->myDetectorType == EIGER) { if (shm()->myDetectorType == EIGER) {
infile.read(reinterpret_cast<char *>(myMod.dacs), infile.read(reinterpret_cast<char *>(myMod.dacs),
@ -3235,16 +3235,15 @@ sls_detector_module Module::readSettingsFile(const std::string &fname,
// mythen3 (dacs, trimbits) // mythen3 (dacs, trimbits)
else if (shm()->myDetectorType == MYTHEN3) { else if (shm()->myDetectorType == MYTHEN3) {
int expected_size = int expected_size = sizeof(int) * myMod.ndac +
sizeof(int) * myMod.ndac + sizeof(int) * myMod.nchan + sizeof(myMod.reg); sizeof(int) * myMod.nchan + sizeof(myMod.reg);
if (file_size != expected_size) { if (file_size != expected_size) {
throw RuntimeError("The size of the settings file: " + fname + throw RuntimeError("The size of the settings file: " + fname +
" differs from the expected size, " + " differs from the expected size, " +
std::to_string(file_size) + " instead of " + std::to_string(file_size) + " instead of " +
std::to_string(expected_size) + " bytes"); std::to_string(expected_size) + " bytes");
} }
infile.read(reinterpret_cast<char *>(&myMod.reg), infile.read(reinterpret_cast<char *>(&myMod.reg), sizeof(myMod.reg));
sizeof(myMod.reg));
infile.read(reinterpret_cast<char *>(myMod.dacs), infile.read(reinterpret_cast<char *>(myMod.dacs),
sizeof(int) * (myMod.ndac)); sizeof(int) * (myMod.ndac));
for (int i = 0; i < myMod.ndac; ++i) { for (int i = 0; i < myMod.ndac; ++i) {

View File

@ -185,7 +185,7 @@ class Module : public virtual slsDetectorDefs {
std::vector<uint64_t> getNumMissingPackets() const; std::vector<uint64_t> getNumMissingPackets() const;
uint64_t getNextFrameNumber() const; uint64_t getNextFrameNumber() const;
void setNextFrameNumber(uint64_t value); void setNextFrameNumber(uint64_t value);
void sendSoftwareTrigger(); void sendSoftwareTrigger(const bool block);
defs::scanParameters getScan() const; defs::scanParameters getScan() const;
void setScan(const defs::scanParameters t); void setScan(const defs::scanParameters t);
std::string getScanErrorMessage() const; std::string getScanErrorMessage() const;

View File

@ -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]") { TEST_CASE("clearbusy", "[.cmd]") {
Detector det; Detector det;
CmdProxy proxy(&det); CmdProxy proxy(&det);