diff --git a/RELEASE.txt b/RELEASE.txt index 22f9a21d4..ff623ecca 100755 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -22,13 +22,16 @@ This document describes the differences between 5.2.0 and 5.1.0 releases. Client ------ - 1. + 1. (Gotthard2) veto streaming + New command to enable/ disable veto streaming via 2.5GbE or/ and 10GbE (debugging). + Command: vetostream, Detector::setVetoStream + + Gotthard2 server + ---------------- - Mythen3 server - ----------------- - - 1. + 1. Bad Channels moved to a new register + 2. Resolved Issues diff --git a/python/scripts/generate_enums.py b/python/scripts/generate_enums.py index e43f45adf..7abb7cfc1 100644 --- a/python/scripts/generate_enums.py +++ b/python/scripts/generate_enums.py @@ -11,14 +11,29 @@ import subprocess from parse import remove_comments +allow_bitwise_op = ["EthernetInterface"] + +op_key = {"operator|": "__or__", + "operator&" : "__and__"} + def single_line_enum(line): sub = line[line.find('{')+1:line.find('}')] return sub.strip().split(',') def extract_enums(lines): + + # deal with enum class EthernetInterface : int32_t + # and normal enum burstMode { + line_iter = iter(lines) enums = {} for line in line_iter: + #Hack away class enum defs + if "class" in line: + line = line.replace("class", "") + line = line.replace(line[line.find(':'):line.find('{')], "") + line = line.replace(" ", " ") + m = re.search("(?<=enum )\w+(?= {)", line) if m: enum_name = m.group() @@ -44,25 +59,80 @@ def extract_enums(lines): pass fields = [f.strip() for f in fields] enums[enum_name] = fields + + + #Loop again to find operators + for key in enums: + for line in lines: + if key in line and "operator" in line: + pos = line.find("operator") + op_type = line[pos:pos+9] + enums[key].append(op_type) return enums + def generate_enum_string(enums): data = [] for key, value in enums.items(): - data.append(f'py::enum_(Defs, "{key}")\n') + if key in allow_bitwise_op: + tag=", py::arithmetic()" + else: + tag="" + data.append(f'py::enum_(Defs, "{key}"{tag})\n') + operators = [] for v in value: - data.append(f'\t.value("{v}", slsDetectorDefs::{key}::{v})\n') - data.append('.export_values();\n\n') + if "operator" not in v: + data.append(f'\t.value("{v}", slsDetectorDefs::{key}::{v})\n') + else: + operators.append(v) + data.append('\t.export_values()') + + #Here add the operators + for op in operators: + data.append(f"\n\t.def(\"{op_key[op]}\", py::overload_cast< const slsDetectorDefs::EthernetInterface&, const slsDetectorDefs::EthernetInterface&>(&{op}))") + + + data.append(';\n\n') return ''.join(data) + +def remove_ifdefs(lines): + """Keeps C++ version of the code""" + out = [] + it = iter(lines) + skip = False + for line in it: + + if "#ifdef __cplusplus" in line: + line = next(it) + + if "#else" in line: + skip = True + + if "#endif" in line: + skip = False + + if not skip and "#endif" not in line: + out.append(line) + return out + + with open('../../slsSupportLib/include/sls/sls_detector_defs.h') as f: data = f.read() data = remove_comments(data) data = data.splitlines() +data = remove_ifdefs(data) enums = extract_enums(data) + + s = generate_enum_string(enums) +# print(s) +# for i, line in enumerate(data): +# print(i, line) + + with open('../src/enums_in.cpp') as f: data = f.read() diff --git a/python/slsdet/detector.py b/python/slsdet/detector.py index f03551ce3..689c49911 100755 --- a/python/slsdet/detector.py +++ b/python/slsdet/detector.py @@ -2212,7 +2212,7 @@ class Detector(CppDetectorApi): @element def veto(self): """ - [Gotthard2] Enable or disable veto data streaming from detector. + [Gotthard2] Enable or disable veto data from chip. Note ---- Default is 0. @@ -2332,6 +2332,18 @@ class Detector(CppDetectorApi): ut.set_using_dict(self.setVetoReference, *args) + @property + @element + def vetostream(self): + return self.getVetoStream() + + @vetostream.setter + def vetostream(self, args): + if not isinstance(args, tuple): + args = (args,) + ut.set_using_dict(self.setVetoStream, *args) + + """ Mythen3 specific """ diff --git a/python/src/detector.cpp b/python/src/detector.cpp index 444248d8b..6ebae6255 100644 --- a/python/src/detector.cpp +++ b/python/src/detector.cpp @@ -1074,6 +1074,16 @@ void init_det(py::module &m) { (void (Detector::*)(const bool, sls::Positions)) & Detector::setVeto, py::arg(), py::arg() = Positions{}) + .def("getVetoStream", + (Result(Detector::*)(sls::Positions) + const) & + Detector::getVetoStream, + py::arg() = Positions{}) + .def("setVetoStream", + (void (Detector::*)(const defs::EthernetInterface, + sls::Positions)) & + Detector::setVetoStream, + py::arg(), py::arg() = Positions{}) .def("getADCConfiguration", (Result(Detector::*)(const int, const int, sls::Positions) const) & diff --git a/python/src/enums.cpp b/python/src/enums.cpp index 92391065d..7e2093224 100644 --- a/python/src/enums.cpp +++ b/python/src/enums.cpp @@ -277,4 +277,20 @@ void init_enums(py::module &m) { .value("TIMING_EXTERNAL", slsDetectorDefs::timingSourceType::TIMING_EXTERNAL) .export_values(); + + py::enum_(Defs, "EthernetInterface", + py::arithmetic()) + .value("NONE", slsDetectorDefs::EthernetInterface::NONE) + .value("I3GBE", slsDetectorDefs::EthernetInterface::I3GBE) + .value("I10GBE", slsDetectorDefs::EthernetInterface::I10GBE) + .value("ALL", slsDetectorDefs::EthernetInterface::ALL) + .export_values() + .def("__or__", + py::overload_cast( + &operator|)) + .def("__and__", + py::overload_cast( + &operator&)); } diff --git a/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h b/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h index 378aed102..8f9204c3b 100644 --- a/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h +++ b/slsDetectorServers/gotthard2DetectorServer/RegisterDefs.h @@ -34,6 +34,10 @@ #define BASE_FLOW_CONTROL (0x00200) // 0x1806_0200 - 0x1806_02FF // https://git.psi.ch/sls_detectors_firmware/vhdl_library/blob/f37608230b4721661f29aacc20124555705ee705/flow/flow_ctrl.vhd +/** Veto processing core */ +#define BASE_VETO_PRCSSNG (0x0300) // 0x1806_0300 - 0x1806_03FF? +// https://git.psi.ch/sls_detectors_firmware/gotthard_II_mcb/blob/master/code/hdl/veto/veto_ctrl.vhd + /* UDP datagram generator */ #define BASE_UDP_RAM (0x01000) // 0x1806_1000 - 0x1806_1FFF @@ -86,7 +90,9 @@ #define CONFIG_VETO_ENBL_OFST (0) #define CONFIG_VETO_ENBL_MSK (0x00000001 << CONFIG_VETO_ENBL_OFST) -#define CONFIG_VETO_CH_10GB_ENBL_OFST (1) +#define CONFIG_VETO_CH_3GB_ENBL_OFST (11) +#define CONFIG_VETO_CH_3GB_ENBL_MSK (0x00000001 << CONFIG_VETO_CH_3GB_ENBL_OFST) +#define CONFIG_VETO_CH_10GB_ENBL_OFST (15) #define CONFIG_VETO_CH_10GB_ENBL_MSK (0x00000001 << CONFIG_VETO_CH_10GB_ENBL_OFST) /* Control RW register */ @@ -110,10 +116,6 @@ /** DTA Offset Register */ #define DTA_OFFSET_REG (0x0A * REG_OFFSET + BASE_CONTROL) -/** Mask Strip Registers (40) */ -#define MASK_STRIP_START_REG (0x18 * REG_OFFSET + BASE_CONTROL) -#define MASK_STRIP_NUM_REGS (40) - /* ASIC registers --------------------------------------------------*/ /* ASIC Config register */ @@ -258,4 +260,10 @@ #define RXR_ENDPOINTS_MAX (32) #define RXR_ENDPOINT_OFST (16 * REG_OFFSET) -// clang-format on \ No newline at end of file + +/** Veto processing core --------------------------------------------------*/ +/** Mask Strip Registers (40) */ +#define MASK_STRIP_START_REG (0x00 * REG_OFFSET + BASE_VETO_PRCSSNG) +#define MASK_STRIP_NUM_REGS (40) + +// clang-format on diff --git a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer index 7b3fd8551..481670565 100755 Binary files a/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer and b/slsDetectorServers/gotthard2DetectorServer/bin/gotthard2DetectorServer_developer differ diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c index 8f4f60087..2ecc00439 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorFunctionList.c @@ -1581,14 +1581,14 @@ enum timingMode getTiming() { void setNumberofUDPInterfaces(int val) { uint32_t addr = CONFIG_REG; - // 2 interfaces (enable veto) + // 2 rxr interfaces (enable debugging interface) if (val > 1) { - LOG(logINFOBLUE, ("Setting #Interfaces: 2 (10gbps veto streaming)\n")); + LOG(logINFOBLUE, ("Enabling 10GbE (debugging) veto streaming\n")); bus_w(addr, bus_r(addr) | CONFIG_VETO_CH_10GB_ENBL_MSK); } - // 1 interface (disable veto) + // 1 rxr interface (disable debugging interface) else { - LOG(logINFOBLUE, ("Setting #Interfaces: 1 (2.5gbps veto streaming)\n")); + LOG(logINFOBLUE, ("Disabling 10GbE (debugging) veto streaming\n")); bus_w(addr, bus_r(addr) & ~CONFIG_VETO_CH_10GB_ENBL_MSK); } LOG(logDEBUG, ("config reg:0x%x\n", bus_r(addr))); @@ -2578,6 +2578,23 @@ int getVeto() { CONFIG_VETO_ENBL_OFST); } +void setVetoStream(int value) { + uint32_t addr = CONFIG_REG; + + if (value) { + LOG(logINFOBLUE, ("Enabling 3GbE veto streaming\n")); + bus_w(addr, bus_r(addr) | CONFIG_VETO_CH_3GB_ENBL_MSK); + } else { + LOG(logINFOBLUE, ("Disabling 3GbE veto streaming\n")); + bus_w(addr, bus_r(addr) & ~CONFIG_VETO_CH_3GB_ENBL_MSK); + } + LOG(logDEBUG, ("config reg:0x%x\n", bus_r(addr))); +} + +int getVetoStream() { + return ((bus_r(CONFIG_REG) & CONFIG_VETO_CH_3GB_ENBL_MSK) ? 1 : 0); +} + void setBadChannels(int nch, int *channels) { LOG(logINFO, ("Setting %d bad channels\n", nch)); diff --git a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h index 43a427489..46db18153 100644 --- a/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h +++ b/slsDetectorServers/gotthard2DetectorServer/slsDetectorServer_defs.h @@ -1,7 +1,7 @@ #pragma once #include "sls/sls_detector_defs.h" -#define REQRD_FRMWRE_VRSN (0x200925) +#define REQRD_FRMWRE_VRSN (0x210527) #define KERNEL_DATE_VRSN "Wed May 20 13:58:38 CEST 2020" #define CTRL_SRVR_INIT_TIME_US (300 * 1000) diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h index 84103f61f..72401feed 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorFunctionList.h @@ -540,6 +540,8 @@ void setTimingSource(enum timingSourceType value); enum timingSourceType getTimingSource(); void setVeto(int enable); int getVeto(); +void setVetoStream(int value); +int getVetoStream(); void setBadChannels(int nch, int *channels); int *getBadChannels(int *nch); #endif diff --git a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h index 62a947254..36a8c96b7 100644 --- a/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h +++ b/slsDetectorServers/slsDetectorServer/include/slsDetectorServer_funcs.h @@ -246,4 +246,6 @@ int is_virtual(int); int get_pattern(int); int load_default_pattern(int); int get_all_threshold_energy(int); -int get_master(int); \ No newline at end of file +int get_master(int); +int get_veto_stream(int); +int set_veto_stream(int); \ No newline at end of file diff --git a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c index 09da78b48..07abf900b 100644 --- a/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c +++ b/slsDetectorServers/slsDetectorServer/src/slsDetectorServer_funcs.c @@ -369,6 +369,8 @@ void function_table() { flist[F_LOAD_DEFAULT_PATTERN] = &load_default_pattern; flist[F_GET_ALL_THRESHOLD_ENERGY] = &get_all_threshold_energy; flist[F_GET_MASTER] = &get_master; + flist[F_GET_VETO_STREAM] = &get_veto_stream; + flist[F_SET_VETO_STREAM] = &set_veto_stream; // check if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) { @@ -7525,7 +7527,7 @@ int get_veto(int file_des) { #endif return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } - +/* int set_veto(int file_des) { ret = OK; memset(mess, 0, sizeof(mess)); @@ -7567,6 +7569,29 @@ int set_veto(int file_des) { #endif return Server_SendResult(file_des, INT32, NULL, 0); } +*/ +int set_veto(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + int arg = 0; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + LOG(logINFO, ("Setting veto mode: %u\n", arg)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + setVeto(arg); + int retval = getVeto(); + LOG(logDEBUG1, ("veto mode retval: %u\n", retval)); + validate(arg, retval, "set veto mode", DEC); + } +#endif + return Server_SendResult(file_des, INT32, NULL, 0); +} int set_pattern(int file_des) { ret = OK; @@ -8383,3 +8408,52 @@ int get_master(int file_des){ #endif return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); } + +int get_veto_stream(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + enum EthernetInterface retval = NONE; + + LOG(logDEBUG1, ("Getting veto stream\n")); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // get only + retval = getVetoStream(); + LOG(logDEBUG1, ("vetostream retval: %u\n", retval)); +#endif + return Server_SendResult(file_des, INT32, &retval, sizeof(retval)); +} + +int set_veto_stream(int file_des) { + ret = OK; + memset(mess, 0, sizeof(mess)); + enum EthernetInterface arg = 0; + + if (receiveData(file_des, &arg, sizeof(arg), INT32) < 0) + return printSocketReadError(); + LOG(logINFO, ("Setting vetostream: %u\n", (int)arg)); + +#ifndef GOTTHARD2D + functionNotImplemented(); +#else + // only set + if (Server_VerifyLock() == OK) { + + if (arg != 0 && arg != 1) { + ret = FAIL; + sprintf(mess, + "Could not set vetostream 3GbE. Invalid argument %d.\n", + arg); + LOG(logERROR, (mess)); + } else { + setVetoStream(arg); + int retval = getVetoStream(); + LOG(logDEBUG1, ("vetostream retval: %u\n", retval)); + validate(arg, retval, "set veto stream", 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 105d95dee..1c582085e 100644 --- a/slsDetectorSoftware/include/sls/Detector.h +++ b/slsDetectorSoftware/include/sls/Detector.h @@ -1244,9 +1244,21 @@ class Detector { /** [Gotthard2] */ Result getVeto(Positions pos = {}) const; - /** [Gotthard2] Default disabled */ + /** [Gotthard2] Veto data in chip, Default disabled */ void setVeto(const bool enable, Positions pos = {}); + /** [Gotthard2] */ + Result getVetoStream(Positions pos = {}) const; + + /** [Gotthard2] Options: NONE (Default), I3GBE, I10GBE (debugging), ALL + * Enable or disable the 2 veto streaming interfaces available. Can + * concatenate more than one interface. \n3GbE (2.5GbE) is the default + * interface to work with. \n10GbE is for debugging and also enables second + * interface in receiver for listening to veto packets (writes a separate + * file if writing enabled). Also restarts client and receiver zmq sockets + * if zmq streaming enabled.*/ + void setVetoStream(const defs::EthernetInterface value, Positions pos = {}); + /** [Gotthard2] */ Result getADCConfiguration(const int chipIndex, const int adcIndex, Positions pos = {}) const; @@ -1727,6 +1739,7 @@ class Detector { private: std::vector getPortNumbers(int start_port); void updateRxRateCorrections(); + void setNumberofUDPInterfaces_(int n, Positions pos); + Result getNumberofUDPInterfaces_(Positions pos) const; }; - } // namespace sls \ No newline at end of file diff --git a/slsDetectorSoftware/src/CmdProxy.cpp b/slsDetectorSoftware/src/CmdProxy.cpp index 9a47d90f9..34dcc73db 100644 --- a/slsDetectorSoftware/src/CmdProxy.cpp +++ b/slsDetectorSoftware/src/CmdProxy.cpp @@ -1802,6 +1802,50 @@ std::string CmdProxy::BurstMode(int action) { return os.str(); } +std::string CmdProxy::VetoStreaming(int action) { + std::ostringstream os; + os << cmd << ' '; + if (action == defs::HELP_ACTION) { + os << "[none|3gbe|10gbe|...]\n\t[Gotthard2] Enable or disable the 2 " + "veto streaming interfaces available. Can include more than one " + "interface. \n\tDefault: none. 3GbE (2.5GbE) is the default " + "interface to work with. \n\t10GbE is for debugging and also " + "enables second interface in receiver for listening to veto " + "packets (writes a separate file if writing enabled). Also " + "restarts client and receiver zmq sockets if zmq streaming " + "enabled." + << '\n'; + } else if (action == defs::GET_ACTION) { + if (!args.empty()) { + WrongNumberOfParameters(0); + } + auto t = det->getVetoStream(std::vector{det_id}); + os << OutString(t) << '\n'; + } else if (action == defs::PUT_ACTION) { + if (args.empty()) { + WrongNumberOfParameters(1); + } + defs::EthernetInterface interface = defs::EthernetInterface::NONE; + for (const auto &arg : args) { + if (arg == "none") { + if (args.size() > 1) { + throw sls::RuntimeError( + "cannot have other arguments with 'none'. args: " + + ToString(args)); + } + break; + } + StringTo(arg); + interface = interface | (StringTo(arg)); + } + det->setVetoStream(interface, std::vector{det_id}); + os << ToString(interface) << '\n'; + } else { + throw sls::RuntimeError("Unknown action"); + } + return os.str(); +} + std::string CmdProxy::ConfigureADC(int action) { std::ostringstream os; os << cmd << ' '; diff --git a/slsDetectorSoftware/src/CmdProxy.h b/slsDetectorSoftware/src/CmdProxy.h index 90bf8dd15..6af69775d 100644 --- a/slsDetectorSoftware/src/CmdProxy.h +++ b/slsDetectorSoftware/src/CmdProxy.h @@ -957,6 +957,7 @@ class CmdProxy { {"currentsource", &CmdProxy::currentsource}, {"timingsource", &CmdProxy::timingsource}, {"veto", &CmdProxy::veto}, + {"vetostream", &CmdProxy::VetoStreaming}, {"confadc", &CmdProxy::ConfigureADC}, {"badchannels", &CmdProxy::BadChannels}, @@ -1132,6 +1133,7 @@ class CmdProxy { std::string VetoReference(int action); std::string VetoFile(int action); std::string BurstMode(int action); + std::string VetoStreaming(int action); std::string ConfigureADC(int action); std::string BadChannels(int action); /* Mythen3 Specific */ @@ -1484,13 +1486,11 @@ class CmdProxy { INTEGER_COMMAND_VEC_ID( numinterfaces, getNumberofUDPInterfaces, setNumberofUDPInterfaces, StringTo, - "[1, 2]\n\t[Jungfrau][Gotthard2] Number of udp interfaces to stream " + "[1, 2]\n\t[Jungfrau] Number of udp interfaces to stream " "data from detector. Default: 1.\n\tAlso enables second interface in " "receiver for listening (Writes a file per interface if writing " "enabled).\n\tAlso restarts client and receiver zmq sockets if zmq " - "streaming enabled.\n\t[Gotthard2] second interface enabled to send " - "veto information via 10Gbps for debugging. By default, if veto " - "enabled, it is sent via 2.5 gbps interface."); + "streaming enabled."); INTEGER_COMMAND_VEC_ID( selinterface, getSelectedUDPInterface, selectUDPInterface, @@ -1913,7 +1913,7 @@ class CmdProxy { INTEGER_COMMAND_VEC_ID(veto, getVeto, setVeto, StringTo, "[0, 1]\n\t[Gotthard2] Enable or disable veto data " - "streaming from detector. Default is 0."); + "data from chip. Default is 0."); /* Mythen3 Specific */ diff --git a/slsDetectorSoftware/src/Detector.cpp b/slsDetectorSoftware/src/Detector.cpp index b0892c2a2..0106f2f1c 100644 --- a/slsDetectorSoftware/src/Detector.cpp +++ b/slsDetectorSoftware/src/Detector.cpp @@ -746,10 +746,28 @@ Result Detector::getScanErrorMessage(Positions pos) const { // Network Configuration (Detector<->Receiver) Result Detector::getNumberofUDPInterfaces(Positions pos) const { - return pimpl->Parallel(&Module::getNumberofUDPInterfaces, pos); + if (getDetectorType().squash() != defs::JUNGFRAU) { + throw sls::RuntimeError( + "Cannot set number of udp interfaces for this detector."); + } + // also called by vetostream (for gotthard2) + return getNumberofUDPInterfaces_(pos); } void Detector::setNumberofUDPInterfaces(int n, Positions pos) { + if (getDetectorType().squash() != defs::JUNGFRAU) { + throw sls::RuntimeError( + "Cannot set number of udp interfaces for this detector."); + } + // also called by vetostream (for gotthard2) + setNumberofUDPInterfaces_(n, pos); +} + +Result Detector::getNumberofUDPInterfaces_(Positions pos) const { + return pimpl->Parallel(&Module::getNumberofUDPInterfaces, pos); +} + +void Detector::setNumberofUDPInterfaces_(int n, Positions pos) { bool previouslyClientStreaming = pimpl->getDataStreamingToClient(); bool useReceiver = getUseReceiverFlag().squash(false); bool previouslyReceiverStreaming = false; @@ -1547,6 +1565,37 @@ void Detector::setVeto(bool enable, Positions pos) { pimpl->Parallel(&Module::setVeto, pos, enable); } +Result Detector::getVetoStream(Positions pos) const { + // 3gbe + auto r3 = pimpl->Parallel(&Module::getVetoStream, pos); + // 10gbe (debugging interface) opens 2nd udp interface in receiver + auto r10 = getNumberofUDPInterfaces_(pos); + + Result res(r3.size()); + for (unsigned int i = 0; i < res.size(); ++i) { + res[i] = (r3[i] ? defs::EthernetInterface::I3GBE + : defs::EthernetInterface::NONE); + if (r10[i] == 2) { + res[i] = res[i] | defs::EthernetInterface::I10GBE; + } + } + return res; +} + +void Detector::setVetoStream(defs::EthernetInterface interface, Positions pos) { + // 3gbe + bool i3gbe = (interface & defs::EthernetInterface::I3GBE) == defs::EthernetInterface::I3GBE; + pimpl->Parallel(&Module::setVetoStream, pos, i3gbe); + + // 10gbe (debugging interface) opens 2nd udp interface in receiver + int old_numinterfaces = getNumberofUDPInterfaces_(pos).tsquash( + "retrieved inconsistent number of udp interfaces"); + int numinterfaces = ((interface & defs::EthernetInterface::I10GBE) == defs::EthernetInterface::I3GBE) ? 2 : 1; + if (numinterfaces != old_numinterfaces) { + setNumberofUDPInterfaces_(numinterfaces, pos); + } + } + Result Detector::getADCConfiguration(const int chipIndex, const int adcIndex, Positions pos) const { diff --git a/slsDetectorSoftware/src/Module.cpp b/slsDetectorSoftware/src/Module.cpp index c5a570ea7..c93fca57b 100644 --- a/slsDetectorSoftware/src/Module.cpp +++ b/slsDetectorSoftware/src/Module.cpp @@ -1870,6 +1870,14 @@ void Module::setVeto(bool enable) { sendToDetector(F_SET_VETO, static_cast(enable), nullptr); } +bool Module::getVetoStream() const { + return (sendToDetector(F_GET_VETO_STREAM)); +} + +void Module::setVetoStream(const bool value) { + sendToDetector(F_SET_VETO_STREAM, static_cast(value), nullptr); +} + int Module::getADCConfiguration(const int chipIndex, const int adcIndex) const { int args[]{chipIndex, adcIndex}; return sendToDetector(F_GET_ADC_CONFIGURATION, args); diff --git a/slsDetectorSoftware/src/Module.h b/slsDetectorSoftware/src/Module.h index a1c52d0f7..81f6bfee1 100644 --- a/slsDetectorSoftware/src/Module.h +++ b/slsDetectorSoftware/src/Module.h @@ -406,6 +406,8 @@ class Module : public virtual slsDetectorDefs { void setTimingSource(slsDetectorDefs::timingSourceType value); bool getVeto() const; void setVeto(bool enable); + bool getVetoStream() const; + void setVetoStream(const bool value); int getADCConfiguration(const int chipIndex, const int adcIndex) const; void setADCConfiguration(const int chipIndex, const int adcIndex, int value); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp index aaedf964e..a42de01a8 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-gotthard2.cpp @@ -639,6 +639,53 @@ TEST_CASE("veto", "[.cmd]") { } } +TEST_CASE("vetostream", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::GOTTHARD2) { + auto prev_val = det.getVetoStream(); + { + std::ostringstream oss; + proxy.Call("vetostream", {"none"}, -1, PUT, oss); + REQUIRE(oss.str() == "vetostream none\n"); + } + { + std::ostringstream oss; + proxy.Call("vetostream", {}, -1, GET, oss); + REQUIRE(oss.str() == "vetostream none\n"); + } + { + std::ostringstream oss; + proxy.Call("vetostream", {"3gbe"}, -1, PUT, oss); + REQUIRE(oss.str() == "vetostream 3gbe\n"); + } + { + std::ostringstream oss; + proxy.Call("vetostream", {}, -1, GET, oss); + REQUIRE(oss.str() == "vetostream 3gbe\n"); + } + { + std::ostringstream oss; + proxy.Call("vetostream", {"3gbe", "10gbe"}, -1, PUT, oss); + REQUIRE(oss.str() == "vetostream 3gbe, 10gbe\n"); + } + { + std::ostringstream oss; + proxy.Call("vetostream", {}, -1, GET, oss); + REQUIRE(oss.str() == "vetostream 3gbe, 10gbe\n"); + } + REQUIRE_THROWS(proxy.Call("vetostream", {"3gbe", "none"}, -1, PUT)); + for (int i = 0; i != det.size(); ++i) { + det.setVetoStream(prev_val[i], {i}); + } + } else { + REQUIRE_THROWS(proxy.Call("vetostream", {}, -1, GET)); + REQUIRE_THROWS(proxy.Call("vetostream", {"none"}, -1, PUT)); + } + REQUIRE_THROWS(proxy.Call("vetostream", {"dfgd"}, -1, GET)); +} + TEST_CASE("confadc", "[.cmd]") { Detector det; CmdProxy proxy(&det); diff --git a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp index aef1f8ee6..9508daeee 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy-jungfrau.cpp @@ -96,6 +96,39 @@ TEST_CASE("Setting and reading back Jungfrau dacs", "[.cmd][.dacs]") { /* Network Configuration (Detector<->Receiver) */ +TEST_CASE("numinterfaces", "[.cmd]") { + Detector det; + CmdProxy proxy(&det); + auto det_type = det.getDetectorType().squash(); + if (det_type == defs::JUNGFRAU) { + auto prev_val = det.getNumberofUDPInterfaces().tsquash( + "inconsistent numinterfaces to test"); + { + std::ostringstream oss; + proxy.Call("numinterfaces", {"2"}, -1, PUT, oss); + REQUIRE(oss.str() == "numinterfaces 2\n"); + } + { + std::ostringstream oss; + proxy.Call("numinterfaces", {"1"}, -1, PUT, oss); + REQUIRE(oss.str() == "numinterfaces 1\n"); + } + { + std::ostringstream oss; + proxy.Call("numinterfaces", {}, -1, GET, oss); + REQUIRE(oss.str() == "numinterfaces 1\n"); + } + det.setNumberofUDPInterfaces(prev_val); + } else { + std::ostringstream oss; + proxy.Call("numinterfaces", {}, -1, GET, oss); + REQUIRE(oss.str() == "numinterfaces 1\n"); + REQUIRE_THROWS(proxy.Call("numinterfaces", {"1"}, -1, PUT)); + } + REQUIRE_THROWS(proxy.Call("numinterfaces", {"3"}, -1, PUT)); + REQUIRE_THROWS(proxy.Call("numinterfaces", {"0"}, -1, PUT)); +} + TEST_CASE("selinterface", "[.cmd]") { Detector det; CmdProxy proxy(&det); diff --git a/slsDetectorSoftware/tests/test-CmdProxy.cpp b/slsDetectorSoftware/tests/test-CmdProxy.cpp index a28fedde2..fe16e345c 100644 --- a/slsDetectorSoftware/tests/test-CmdProxy.cpp +++ b/slsDetectorSoftware/tests/test-CmdProxy.cpp @@ -1751,39 +1751,6 @@ TEST_CASE("scanerrmsg", "[.cmd]") { /* Network Configuration (Detector<->Receiver) */ -TEST_CASE("numinterfaces", "[.cmd]") { - Detector det; - CmdProxy proxy(&det); - auto det_type = det.getDetectorType().squash(); - if (det_type == defs::JUNGFRAU || det_type == defs::GOTTHARD2) { - auto prev_val = det.getNumberofUDPInterfaces().tsquash( - "inconsistent numinterfaces to test"); - { - std::ostringstream oss; - proxy.Call("numinterfaces", {"2"}, -1, PUT, oss); - REQUIRE(oss.str() == "numinterfaces 2\n"); - } - { - std::ostringstream oss; - proxy.Call("numinterfaces", {"1"}, -1, PUT, oss); - REQUIRE(oss.str() == "numinterfaces 1\n"); - } - { - std::ostringstream oss; - proxy.Call("numinterfaces", {}, -1, GET, oss); - REQUIRE(oss.str() == "numinterfaces 1\n"); - } - det.setNumberofUDPInterfaces(prev_val); - } else { - std::ostringstream oss; - proxy.Call("numinterfaces", {}, -1, GET, oss); - REQUIRE(oss.str() == "numinterfaces 1\n"); - REQUIRE_THROWS(proxy.Call("numinterfaces", {"1"}, -1, PUT)); - } - REQUIRE_THROWS(proxy.Call("numinterfaces", {"3"}, -1, PUT)); - REQUIRE_THROWS(proxy.Call("numinterfaces", {"0"}, -1, PUT)); -} - TEST_CASE("udp_srcip", "[.cmd]") { Detector det; CmdProxy proxy(&det); diff --git a/slsSupportLib/include/sls/ToString.h b/slsSupportLib/include/sls/ToString.h index 1d13d849a..65ace1e8c 100644 --- a/slsSupportLib/include/sls/ToString.h +++ b/slsSupportLib/include/sls/ToString.h @@ -36,6 +36,7 @@ std::string ToString(const defs::dacIndex s); std::string ToString(const std::vector &vec); std::string ToString(const defs::burstMode s); std::string ToString(const defs::timingSourceType s); +std::string ToString(const defs::EthernetInterface s); std::string ToString(const slsDetectorDefs::xy &coord); std::ostream &operator<<(std::ostream &os, const slsDetectorDefs::xy &coord); @@ -297,6 +298,7 @@ template <> defs::readoutMode StringTo(const std::string &s); template <> defs::dacIndex StringTo(const std::string &s); template <> defs::burstMode StringTo(const std::string &s); template <> defs::timingSourceType StringTo(const std::string &s); +template <> defs::EthernetInterface StringTo(const std::string &s); template <> uint32_t StringTo(const std::string &s); template <> uint64_t StringTo(const std::string &s); diff --git a/slsSupportLib/include/sls/sls_detector_defs.h b/slsSupportLib/include/sls/sls_detector_defs.h index 3e2c4bbee..13d7f89e2 100644 --- a/slsSupportLib/include/sls/sls_detector_defs.h +++ b/slsSupportLib/include/sls/sls_detector_defs.h @@ -394,6 +394,17 @@ typedef struct { */ enum timingSourceType { TIMING_INTERNAL, TIMING_EXTERNAL }; +#ifdef __cplusplus + enum class EthernetInterface { +#else + enum EthernetInterface { +#endif + NONE = 0, + I3GBE = 1 << 1, + I10GBE = 1 << 2, + ALL = I3GBE | I10GBE + }; + #ifdef __cplusplus /** scan structure */ @@ -485,8 +496,18 @@ typedef struct { #ifdef __cplusplus }; +inline slsDetectorDefs::EthernetInterface +operator|( const slsDetectorDefs::EthernetInterface &a, + const slsDetectorDefs::EthernetInterface &b) { + return slsDetectorDefs::EthernetInterface(static_cast(a) | + static_cast(b)); +}; + +inline slsDetectorDefs::EthernetInterface operator&( const slsDetectorDefs::EthernetInterface &a, + const slsDetectorDefs::EthernetInterface &b) { + return slsDetectorDefs::EthernetInterface(static_cast(a) & static_cast(b)); +}; #endif -; #ifdef __cplusplus struct detParameters { @@ -632,3 +653,4 @@ using Positions = const std::vector &; using defs = slsDetectorDefs; } // namespace sls #endif + diff --git a/slsSupportLib/include/sls/sls_detector_funcs.h b/slsSupportLib/include/sls/sls_detector_funcs.h index 9abb18d7f..34a772671 100755 --- a/slsSupportLib/include/sls/sls_detector_funcs.h +++ b/slsSupportLib/include/sls/sls_detector_funcs.h @@ -221,6 +221,8 @@ enum detFuncs { F_LOAD_DEFAULT_PATTERN, F_GET_ALL_THRESHOLD_ENERGY, F_GET_MASTER, + F_GET_VETO_STREAM, + F_SET_VETO_STREAM, NUM_DET_FUNCTIONS, RECEIVER_ENUM_START = 256, /**< detector function should not exceed this @@ -548,6 +550,9 @@ 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_VETO_STREAM: return "F_GET_VETO_STREAM"; + case F_SET_VETO_STREAM: return "F_SET_VETO_STREAM"; + case NUM_DET_FUNCTIONS: return "NUM_DET_FUNCTIONS"; case RECEIVER_ENUM_START: return "RECEIVER_ENUM_START"; diff --git a/slsSupportLib/include/sls/versionAPI.h b/slsSupportLib/include/sls/versionAPI.h index 058b5be80..c3c69e557 100644 --- a/slsSupportLib/include/sls/versionAPI.h +++ b/slsSupportLib/include/sls/versionAPI.h @@ -1,12 +1,12 @@ /** API versions */ #define GITBRANCH "5.1.0" -#define APICTB 0x210225 -#define APIGOTTHARD 0x210225 -#define APIMOENCH 0x210225 -#define APIEIGER 0x210225 -#define APIMYTHEN3 0x210225 -#define APILIB 0x210225 -#define APIRECEIVER 0x210225 -#define APIGUI 0x210225 -#define APIGOTTHARD2 0x210714 -#define APIJUNGFRAU 0x210714 +#define APICTB 0x210225 +#define APIGOTTHARD 0x210225 +#define APIJUNGFRAU 0x210714 +#define APIMOENCH 0x210225 +#define APIEIGER 0x210225 +#define APIMYTHEN3 0x210225 +#define APILIB 0x210225 +#define APIRECEIVER 0x210225 +#define APIGUI 0x210225 +#define APIGOTTHARD2 0x210715 diff --git a/slsSupportLib/src/ToString.cpp b/slsSupportLib/src/ToString.cpp index 97b9025fd..4db40a60b 100644 --- a/slsSupportLib/src/ToString.cpp +++ b/slsSupportLib/src/ToString.cpp @@ -519,6 +519,23 @@ std::string ToString(const defs::timingSourceType s) { } } +std::string ToString(const defs::EthernetInterface s) { + std::ostringstream os; + std::string rs; + switch (s) { + case defs::EthernetInterface::NONE: + return std::string("none"); + default: + if ((s & defs::EthernetInterface::I3GBE)!=defs::EthernetInterface::NONE) + os << "3gbe, "; + if ((s & defs::EthernetInterface::I10GBE)!=defs::EthernetInterface::NONE) + os << "10gbe, "; + auto rs = os.str(); + rs.erase(rs.end() - 2, rs.end()); + return rs; + } +} + const std::string &ToString(const std::string &s) { return s; } template <> defs::detectorType StringTo(const std::string &s) { @@ -859,6 +876,19 @@ template <> defs::timingSourceType StringTo(const std::string &s) { throw sls::RuntimeError("Unknown timing source type " + s); } +template <> defs::EthernetInterface StringTo(const std::string &s) { + std::string rs = s; + if (s.find(',') != std::string::npos) + rs.erase(rs.find(',')); + if (rs == "none") + return defs::EthernetInterface::NONE; + if (rs == "3gbe") + return defs::EthernetInterface::I3GBE; + if (rs == "10gbe") + return defs::EthernetInterface::I10GBE; + throw sls::RuntimeError("Unknown EthernetInterface type " + s); +} + template <> uint32_t StringTo(const std::string &s) { int base = s.find("0x") != std::string::npos ? 16 : 10; return std::stoul(s, nullptr, base); diff --git a/slsSupportLib/tests/test-Sockets.cpp b/slsSupportLib/tests/test-Sockets.cpp index ef1dc6696..7a114b056 100644 --- a/slsSupportLib/tests/test-Sockets.cpp +++ b/slsSupportLib/tests/test-Sockets.cpp @@ -4,6 +4,7 @@ #include #include #include +#include std::vector server() { std::cout << "starting server\n"; diff --git a/slsSupportLib/tests/test-ToString.cpp b/slsSupportLib/tests/test-ToString.cpp index 46a95f33a..e372f9336 100644 --- a/slsSupportLib/tests/test-ToString.cpp +++ b/slsSupportLib/tests/test-ToString.cpp @@ -1,10 +1,10 @@ #include "catch.hpp" +#include "sls/Pattern.h" #include "sls/TimeHelper.h" #include "sls/ToString.h" -#include "sls/network_utils.h" -#include "sls/Pattern.h" -#include "sls/sls_detector_defs.h" #include "sls/container_utils.h" +#include "sls/network_utils.h" +#include "sls/sls_detector_defs.h" #include #include #include @@ -302,25 +302,32 @@ TEST_CASE("Streaming of slsDetectorDefs::scanParameters") { } } -TEST_CASE("Printing c style arrays of int"){ +TEST_CASE("Printing c style arrays of int") { int arr[]{3, 5}; REQUIRE(ToString(arr) == "[3, 5]"); } -TEST_CASE("Printing c style arrays of uint8"){ - uint8_t arr[]{1,2,3,4,5}; +TEST_CASE("Printing c style arrays of uint8") { + uint8_t arr[]{1, 2, 3, 4, 5}; REQUIRE(ToString(arr) == "[1, 2, 3, 4, 5]"); } -TEST_CASE("Printing c style arrays of double"){ +TEST_CASE("Printing c style arrays of double") { double arr[]{3.4, 5.3, 6.2}; REQUIRE(ToString(arr) == "[3.4, 5.3, 6.2]"); } -TEST_CASE("Print a member of patternParameters"){ +TEST_CASE("Print a member of patternParameters") { auto pat = sls::make_unique(); pat->limits[0] = 4; pat->limits[1] = 100; REQUIRE(ToString(pat->limits) == "[4, 100]"); +} +TEST_CASE("EthernetInterface") { + REQUIRE(ToString(sls::defs::EthernetInterface::NONE) == "none"); + REQUIRE(ToString(sls::defs::EthernetInterface::I10GBE) == "10gbe"); + REQUIRE(ToString(sls::defs::EthernetInterface::I3GBE) == "3gbe"); + REQUIRE(ToString(sls::defs::EthernetInterface::I3GBE | + sls::defs::EthernetInterface::I10GBE) == "3gbe, 10gbe"); } \ No newline at end of file