From 801f2c45591ffea511bc7ac03f4a8ff2820acee1 Mon Sep 17 00:00:00 2001 From: Dhanya Thattil Date: Mon, 22 Jun 2020 09:33:09 +0200 Subject: [PATCH] WIP --- .../slsDetectorFunctionList.c | 23 ++-- .../slsDetectorFunctionList.c | 23 ++-- .../slsDetectorFunctionList.c | 25 ++-- .../include/slsDetectorServer_funcs.h | 3 +- .../src/slsDetectorServer_funcs.c | 124 +++++++++++++++++- slsDetectorSoftware/src/CmdProxy.cpp | 5 +- slsDetectorSoftware/src/Module.cpp | 122 +++++++++++++++-- slsSupportLib/include/ToString.h | 3 + slsSupportLib/include/sls_detector_defs.h | 14 ++ slsSupportLib/include/sls_detector_funcs.h | 2 + slsSupportLib/src/ToString.cpp | 37 ++++++ 11 files changed, 323 insertions(+), 58 deletions(-) diff --git a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c index 36cbe0c04..9897e753c 100644 --- a/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/ctbDetectorServer/slsDetectorFunctionList.c @@ -1956,8 +1956,8 @@ uint64_t writePatternWord(int addr, uint64_t word) { return -1; } - LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr, - (long long int)word)); + LOG(logDEBUG1, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr, + (long long int)word)); uint32_t reg = PATTERN_CNTRL_REG; // write word @@ -2150,18 +2150,15 @@ void setPatternLoop(int level, int *startAddr, int *stopAddr, int *nLoop) { LOG(logDEBUG1, ("Addr:0x%x, val:0x%x\n", addr, bus_r(addr))); } - // get - else { - *startAddr = ((bus_r(addr) & startMask) >> startOffset); - LOG(logDEBUG1, ("Getting Pattern Loop Start Address (level:%d, Read " - "startAddr:0x%x)\n", - level, *startAddr)); + *startAddr = ((bus_r(addr) & startMask) >> startOffset); + LOG(logDEBUG1, ("Getting Pattern Loop Start Address (level:%d, Read " + "startAddr:0x%x)\n", + level, *startAddr)); - *stopAddr = ((bus_r(addr) & stopMask) >> stopOffset); - LOG(logDEBUG1, ("Getting Pattern Loop Stop Address (level:%d, Read " - "stopAddr:0x%x)\n", - level, *stopAddr)); - } + *stopAddr = ((bus_r(addr) & stopMask) >> stopOffset); + LOG(logDEBUG1, ("Getting Pattern Loop Stop Address (level:%d, Read " + "stopAddr:0x%x)\n", + level, *stopAddr)); } int setLEDEnable(int enable) { diff --git a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c index 4da87e699..a9bf6b2c3 100644 --- a/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/moenchDetectorServer/slsDetectorFunctionList.c @@ -1630,8 +1630,8 @@ uint64_t writePatternWord(int addr, uint64_t word) { return -1; } - LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr, - (long long int)word)); + LOG(logDEBUG1, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr, + (long long int)word)); uint32_t reg = PATTERN_CNTRL_REG; // write word @@ -1824,18 +1824,15 @@ void setPatternLoop(int level, int *startAddr, int *stopAddr, int *nLoop) { LOG(logDEBUG1, ("Addr:0x%x, val:0x%x\n", addr, bus_r(addr))); } - // get - else { - *startAddr = ((bus_r(addr) & startMask) >> startOffset); - LOG(logDEBUG1, ("Getting Pattern Loop Start Address (level:%d, Read " - "startAddr:0x%x)\n", - level, *startAddr)); + *startAddr = ((bus_r(addr) & startMask) >> startOffset); + LOG(logDEBUG1, ("Getting Pattern Loop Start Address (level:%d, Read " + "startAddr:0x%x)\n", + level, *startAddr)); - *stopAddr = ((bus_r(addr) & stopMask) >> stopOffset); - LOG(logDEBUG1, ("Getting Pattern Loop Stop Address (level:%d, Read " - "stopAddr:0x%x)\n", - level, *stopAddr)); - } + *stopAddr = ((bus_r(addr) & stopMask) >> stopOffset); + LOG(logDEBUG1, ("Getting Pattern Loop Stop Address (level:%d, Read " + "stopAddr:0x%x)\n", + level, *stopAddr)); } void setPatternMask(uint64_t mask) { diff --git a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c index db2e50022..391e938a8 100644 --- a/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/mythen3DetectorServer/slsDetectorFunctionList.c @@ -1491,7 +1491,7 @@ uint64_t readPatternWord(int addr) { return -1; } - LOG(trimmingPrint, (" Reading Pattern Word (addr:0x%x)\n", addr)); + LOG(logDEBUG1, (" Reading Pattern Word (addr:0x%x)\n", addr)); uint32_t reg_lsb = PATTERN_STEP0_LSB_REG + addr * REG_OFFSET * 2; // the first word in RAM as base plus the offset @@ -1519,8 +1519,8 @@ uint64_t writePatternWord(int addr, uint64_t word) { addr, MAX_PATTERN_LENGTH)); return -1; } - LOG(trimmingPrint, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr, - (long long int)word)); + LOG(logDEBUG1, ("Setting Pattern Word (addr:0x%x, word:0x%llx)\n", addr, + (long long int)word)); // write word uint32_t reg_lsb = @@ -1710,18 +1710,15 @@ void setPatternLoop(int level, int *startAddr, int *stopAddr, int *nLoop) { ((*stopAddr << stopOffset) & stopMask)); } - // get - else { - *startAddr = ((bus_r(addr) & startMask) >> startOffset); - LOG(logDEBUG1, ("Getting Pattern Loop Start Address (level:%d, Read " - "startAddr:0x%x)\n", - level, *startAddr)); + *startAddr = ((bus_r(addr) & startMask) >> startOffset); + LOG(logDEBUG1, ("Getting Pattern Loop Start Address (level:%d, Read " + "startAddr:0x%x)\n", + level, *startAddr)); - *stopAddr = ((bus_r(addr) & stopMask) >> stopOffset); - LOG(logDEBUG1, ("Getting Pattern Loop Stop Address (level:%d, Read " - "stopAddr:0x%x)\n", - level, *stopAddr)); - } + *stopAddr = ((bus_r(addr) & stopMask) >> stopOffset); + LOG(logDEBUG1, ("Getting Pattern Loop Stop Address (level:%d, Read " + "stopAddr:0x%x)\n", + level, *stopAddr)); } void setPatternMask(uint64_t mask) { diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index b79faebd3..34a65d8c8 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -221,4 +221,5 @@ int get_gate_delay(int); int get_exptime_all_gates(int); int get_gate_delay_all_gates(int); int get_veto(int); -int set_veto(int); \ No newline at end of file +int set_veto(int); +int set_pattern(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 397ef8011..fce9e7bb2 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -332,6 +332,7 @@ void function_table() { flist[F_GET_GATE_DELAY_ALL_GATES] = &get_gate_delay_all_gates; flist[F_GET_VETO] = &get_veto; flist[F_SET_VETO] = &set_veto; + flist[F_SET_PATTERN] = &set_pattern; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -2917,8 +2918,8 @@ int set_pattern_word(int file_des) { #else int addr = (int)args[0]; uint64_t word = args[1]; - LOG(logDEBUG1, ("Setting Pattern Word (addr:0x%x, word:0x%llx\n", addr, - (long long int)word)); + LOG(logINFO, ("Setting Pattern Word (addr:0x%x, word:0x%llx\n", addr, + (long long int)word)); if (Server_VerifyLock() == OK) { // valid address if (addr < 0 || addr >= MAX_PATTERN_LENGTH) { @@ -7357,3 +7358,122 @@ int set_veto(int file_des) { #endif return Server_SendResult(file_des, INT32, NULL, 0); } + +int set_pattern(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + uint64_t word[MAX_PATTERN_LENGTH]; + memset(word, 0, sizeof(word)); + uint64_t patioctrl = 0; + uint64_t patclkctrl = 0; + uint32_t patlimits[2] = {0, 0}; + uint32_t patloop[6] = {0, 0, 0, 0, 0, 0}; + uint32_t patnloop[3] = {0, 0, 0}; + uint32_t patwait[3] = {0, 0, 0}; + uint64_t patwaittime[3] = {0, 0, 0}; + if (receiveData(file_des, word, sizeof(word), INT64) < 0) + return printSocketReadError(); + if (receiveData(file_des, &patioctrl, sizeof(patioctrl), INT64) < 0) + return printSocketReadError(); + if (receiveData(file_des, &patclkctrl, sizeof(patclkctrl), INT64) < 0) + return printSocketReadError(); + if (receiveData(file_des, patlimits, sizeof(patlimits), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, patloop, sizeof(patloop), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, patwait, sizeof(patwait), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, patlimits, sizeof(patlimits), INT32) < 0) + return printSocketReadError(); + if (receiveData(file_des, patwaittime, sizeof(patwaittime), INT64) < 0) + return printSocketReadError(); + +#if !defined(CHIPTESTBOARDD) && !defined(MOENCHD) && !defined(MYTHEN3D) + functionNotImplemented(); +#else + if (Server_VerifyLock() == OK) { + LOG(logINFO, ("Setting Pattern Word\n"); + for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) { + writePatternWord(i, word[i]); + } + int numLoops = -1, retval0 = -1, retval1 = -1; + uint64_t retval64 = -1; +#ifndef MYTHEN3D + if (ret == OK) { + retval64 = writePatternIOControl(patioctrl); + validate64(patioctrl, retval64, "Pattern IO Control", HEX); + } + if (ret == OK) { + retval64 = writePatternClkControl(patclkctrl); + validate64(patclkctrl, retval64, "Pattern Clock Control", HEX); + } +#endif + if (ret == OK) { + numLoops = -1; + retval0 = patlimits[0]; + retval1 = patlimits[1]; + setPatternLoop(-1, &retval0, &retval1, &numLoops); + setPatternLoop(-1, &retval0, &retval1, &numLoops); + validate(patlimits[0], retval0, "Pattern Limits start address", + HEX); + validate(patlimits[1], retval1, "Pattern Limits start address", + HEX); + } + if (ret == OK) { + retval0 = patloop[0]; + retval1 = patnloop[1]; + numLoops = patnloop[0]; + setPatternLoop(0, &patloop[0], &patloop[1], &patnloop[0]); + validate(patloop[0], retval0, "Pattern Loop 0 start address", HEX); + validate(patloop[1], retval1, "Pattern Loop 0 stop address", HEX); + validate(patnloop[0], numLoops, "Pattern Loop 0 num loops", HEX); + } + if (ret == OK) { + retval0 = patloop[2]; + retval1 = patnloop[3]; + numLoops = patnloop[1]; + setPatternLoop(1, &patloop[2], &patloop[3], &patnloop[1]); + validate(patloop[2], retval0, "Pattern Loop 1 start address", HEX); + validate(patloop[3], retval1, "Pattern Loop 1 stop address", HEX); + validate(patnloop[1], numLoops, "Pattern Loop 1 num loops", HEX); + } + if (ret == OK) { + retval0 = patloop[4]; + retval1 = patnloop[5]; + numLoops = patnloop[2]; + setPatternLoop(2, &patloop[4], &patloop[5], &patnloop[2]); + validate(patloop[4], retval0, "Pattern Loop 2 start address", HEX); + validate(patloop[5], retval1, "Pattern Loop 2 stop address", HEX); + validate(patnloop[2], numLoops, "Pattern Loop 2 num loops", HEX); + } + if (ret == OK) { + retval0 = setPatternWaitAddress(0, &patwait[0]); + validate(patwait[0], retval0, "Pattern Loop 0 wait address", HEX); + } + if (ret == OK) { + retval0 = setPatternWaitAddress(1, &patwait[1]); + validate(patwait[1], retval0, "Pattern Loop 1 wait address", HEX); + } + if (ret == OK) { + retval0 = setPatternWaitAddress(2, &patwait[2]); + validate(patwait[2], retval0, "Pattern Loop 2 wait address", HEX); + } + if (ret == OK) { + uint64_t retval64 = setPatternWaitTime(0, &patwaittime[0]); + validate64(patwaittime[0], retval64, "Pattern Loop 0 wait time", + HEX); + } + if (ret == OK) { + retval64 = setPatternWaitTime(1, &patwaittime[1]); + validate64(patwaittime[1], retval64, "Pattern Loop 1 wait time", + HEX); + } + if (ret == OK) { + retval64 = setPatternWaitTime(2, &patwaittime[2]); + validate64(patwaittime[1], retval64, "Pattern Loop 2 wait time", + HEX); + } + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} \ No newline at end of file diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 6dedea34d..35ce144be 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1940,9 +1940,8 @@ std::string CmdProxy::Pattern(int action) { std::ostringstream os; os << cmd << ' '; if (action == defs::HELP_ACTION) { - os << "[fname]\n\t[Mythen3][Moench][Ctb] Loads binary pattern " - "file with only pattern " - "words" + os << "[fname]\n\t[Mythen3][Moench][Ctb] Loads ASCII pattern file " + "directly to server (instead of executing line by line)" << '\n'; } else if (action == defs::GET_ACTION) { throw sls::RuntimeError("Cannot get"); diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index 725d9bafe..65ba17699 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include namespace sls { @@ -1746,19 +1747,116 @@ void Module::setLEDEnable(bool enable) { // Pattern void Module::setPattern(const std::string &fname) { - uint64_t word; - uint64_t addr = 0; - FILE *fd = fopen(fname.c_str(), "r"); - if (fd != nullptr) { - while (fread(&word, sizeof(word), 1, fd) != 0U) { - setPatternWord(addr, word); // TODO! (Erik) do we need to send - // pattern in 64bit chunks? - ++addr; - } - fclose(fd); - } else { - throw RuntimeError("Could not open file to set pattern"); + patternParameters pat; + memset(&pat, 0, sizeof(pat)); + std::ifstream input_file; + input_file.open(fname.c_str(), std::ios_base::in); + if (!input_file.is_open()) { + throw RuntimeError("Could not open pattern file " + fname + + " for reading"); } + std::string current_line; + while (input_file.good()) { + getline(input_file, current_line); + if (current_line.find('#') != std::string::npos) { + current_line.erase(current_line.find('#')); + } + LOG(logDEBUG1) << "current_line after removing comments:\n\t" + << current_line; + if (current_line.length() > 1) { + + // convert command and string to a vector + std::istringstream iss(current_line); + auto it = std::istream_iterator(iss); + std::vector args = std::vector( + it, std::istream_iterator()); + + std::string cmd = args[0]; + int nargs = args.size() - 1; + + if (cmd == "patword") { + if (nargs != 2) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + uint32_t addr = StringTo(args[1]); + if (addr >= MAX_PATTERN_LENGTH) { + throw RuntimeError("Invalid address for " + ToString(args)); + } + pat.word[addr] = StringTo(args[2]); + } else if (cmd == "patioctrl") { + if (nargs != 1) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + pat.patioctrl = StringTo(args[1]); + } else if (cmd == "patclkctrl") { + if (nargs != 1) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + pat.patclkctrl = StringTo(args[1]); + } else if (cmd == "patlimits") { + if (nargs != 2) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + pat.patlimits[0] = StringTo(args[1]); + pat.patlimits[1] = StringTo(args[2]); + if (pat.patlimits[0] >= MAX_PATTERN_LENGTH || + pat.patlimits[1] >= MAX_PATTERN_LENGTH) { + throw RuntimeError("Invalid address for " + ToString(args)); + } + } else if (cmd == "patloop0" || cmd == "patloop1" || + cmd == "patloop2") { + if (nargs != 2) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + int level = cmd[cmd.find_first_of("012")] - '0'; + int patloop1 = StringTo(args[1]); + int patloop2 = StringTo(args[2]); + pat.patloop[level * 2 + 0] = patloop1; + pat.patloop[level * 2 + 1] = patloop2; + if (patloop1 >= MAX_PATTERN_LENGTH || + patloop2 >= MAX_PATTERN_LENGTH) { + throw RuntimeError("Invalid address for " + ToString(args)); + } + } else if (cmd == "patnloop0" || cmd == "patnloop1" || + cmd == "patnloop2") { + if (nargs != 1) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + int level = cmd[cmd.find_first_of("012")] - '0'; + pat.patnloop[level] = StringTo(args[1]); + } else if (cmd == "patwait0" || cmd == "patwait1" || + cmd == "patwait2") { + if (nargs != 1) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + int level = cmd[cmd.find_first_of("012")] - '0'; + pat.patwait[level] = StringTo(args[1]); + if (pat.patwait[level] >= MAX_PATTERN_LENGTH) { + throw RuntimeError("Invalid address for " + ToString(args)); + } + } else if (cmd == "patwaittime0" || cmd == "patwaittime1" || + cmd == "patwaittime2") { + if (nargs != 1) { + throw RuntimeError("Invalid arguments for " + + ToString(args)); + } + int level = cmd[cmd.find_first_of("012")] - '0'; + pat.patwaittime[level] = StringTo(args[1]); + } else { + throw RuntimeError("Unknown command in pattern file " + cmd); + } + } + } + input_file.close(); + std::cout << "sizeof pat:" << sizeof(pat) << std::endl; + sendToDetector(F_SET_PATTERN, pat); } uint64_t Module::getPatternIOControl() { diff --git a/slsSupportLib/include/ToString.h b/slsSupportLib/include/ToString.h index ff2db057f..23c533bda 100644 --- a/slsSupportLib/include/ToString.h +++ b/slsSupportLib/include/ToString.h @@ -44,6 +44,9 @@ std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::ROI &roi); std::string ToString(const slsDetectorDefs::rxParameters &r); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::rxParameters &r); +std::string ToString(const slsDetectorDefs::patternParameters &r); +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::patternParameters &r); const std::string &ToString(const std::string &s); /** Convert std::chrono::duration with specified output unit */ diff --git a/slsSupportLib/include/sls_detector_defs.h b/slsSupportLib/include/sls_detector_defs.h index 203e0f132..d90c3f7f3 100644 --- a/slsSupportLib/include/sls_detector_defs.h +++ b/slsSupportLib/include/sls_detector_defs.h @@ -61,6 +61,8 @@ #define MAX_STR_LENGTH 1000 #define SHORT_STR_LENGTH 20 +#define MAX_PATTERN_LENGTH 0x2000 + #define DEFAULT_STREAMING_TIMER_IN_MS 200 #define NUM_RX_THREAD_IDS 8 @@ -437,6 +439,18 @@ typedef struct { int64_t gateDelay3Ns{0}; int gates{0}; } __attribute__((packed)); + + /** pattern structure */ + struct patternParameters { + uint64_t word[MAX_PATTERN_LENGTH]; + uint64_t patioctrl; + uint64_t patclkctrl; + uint32_t patlimits[2]; + uint32_t patloop[6]; + uint32_t patnloop[3]; + uint32_t patwait[3]; + uint64_t patwaittime[3]; + } __attribute__((packed)); #endif #ifdef __cplusplus diff --git a/slsSupportLib/include/sls_detector_funcs.h b/slsSupportLib/include/sls_detector_funcs.h index a0fd9137d..ae8e4d38f 100755 --- a/slsSupportLib/include/sls_detector_funcs.h +++ b/slsSupportLib/include/sls_detector_funcs.h @@ -201,6 +201,7 @@ enum detFuncs { F_GET_GATE_DELAY_ALL_GATES, F_GET_VETO, F_SET_VETO, + F_SET_PATTERN, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -500,6 +501,7 @@ const char* getFunctionNameFromEnum(enum detFuncs func) { case F_GET_GATE_DELAY_ALL_GATES: return "F_GET_GATE_DELAY_ALL_GATES"; case F_GET_VETO: return "F_GET_VETO"; case F_SET_VETO: return "F_SET_VETO"; + case F_SET_PATTERN: return "F_SET_PATTERN"; case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index e57727957..121db4233 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -64,6 +64,43 @@ std::ostream &operator<<(std::ostream &os, return os << ToString(r); } +std::string ToString(const slsDetectorDefs::patternParameters &r) { + std::ostringstream oss; + oss << '[' << std::endl; + for (int i = 0; i < MAX_PATTERN_LENGTH; ++i) { + if (r.word[i] != 0) { + oss << "patword 0x" << std::hex << i << " 0x" << std::hex + << r.word[i] << std::endl; + } + } + oss << "patioctrl 0x" << std::hex << r.patioctrl << std::endl + << "patclkctrl 0x" << r.patclkctrl << std::endl + << "patlimits 0x" << r.patlimits[0] << " 0x" << r.patlimits[1] + << std::endl + << "patloop0 0x" << r.patloop[0] << " 0x" << r.patloop[1] << std::endl + << "patnloop0 " << std::dec << r.patnloop[0] << std::hex << std::endl + << "patloop1 0x" << r.patloop[2] << " 0x" << r.patloop[3] << std::endl + << "patnloop1 " << std::dec << r.patnloop[1] << std::hex << std::endl + << "patloop2 0x" << r.patloop[4] << " 0x" << r.patloop[5] << std::endl + << "patnloop2 " << std::dec << r.patnloop[2] << std::hex << std::endl + << "patwait0 0x" << r.patwait[0] << std::endl + << "patwaittime0 " << std::dec << r.patwaittime[0] << std::hex + << std::endl + << "patwait1 0x" << r.patwait[1] << std::endl + << "patwaittime1 " << std::dec << r.patwaittime[1] << std::hex + << std::endl + << "patwait1 0x" << r.patwait[1] << std::endl + << "patwaittime2 " << std::dec << r.patwaittime[2] << std::hex + << std::endl + << ']'; + return oss.str(); +} + +std::ostream &operator<<(std::ostream &os, + const slsDetectorDefs::patternParameters &r) { + return os << ToString(r); +} + std::string ToString(const defs::runStatus s) { switch (s) { case defs::ERROR: