merge conflict

This commit is contained in:
maliakal_d 2021-07-22 11:15:57 +02:00
commit da996314e7
28 changed files with 655 additions and 116 deletions

View File

@ -1,7 +1,7 @@
SLS Detector Package 5.X.X released on XX.XX.2021 (Minor Release)
SLS Detector Package 5.2.0 released on 15.07.2021 (Minor Release)
===================================================================
This document describes the differences between X and Y releases.
This document describes the differences between 5.2.0 and 5.1.0 releases.
@ -19,17 +19,69 @@ This document describes the differences between X and Y releases.
1. New Features
===============
Setting Mythen3 gain from command line
Client
------
1. Setting Mythen3 gain from command line
4. Firmware Requirements
2. (Gotthard2) veto streaming
New command to enable/ disable veto streaming via 2.5GbE or/ and 10GbE (debugging).
Command: vetostream, Detector::setVetoStream
Gotthard2 server
----------------
1. Bad Channels moved to a new register
2. Resolved Issues
==================
Receiver
--------
1.
Client
------
1.
Gotthard2 Server
----------------
1. Tolerance in time parameters.
Eg. 220 ns was being set to 215 ns, instead of 222ns.
Jungfrau Server
----------------
1. Stopping in trigger mode and then switching to auto timing mode
blocks data streaming from detector. Workaround fix made in
detector server to reset core until firmware release.
3. Firmware Requirements
========================
Gotthard2: 0x210201 ???
Other detectors no updates from 5.1.0
5. Known Issues
===============
No updates from 5.0.0
No updates from 5.1.0

View File

@ -12,15 +12,29 @@ import subprocess
from parse import remove_comments
allow_bitwise_op = ["M3_GainCaps"]
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()
@ -46,8 +60,18 @@ 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():
@ -56,19 +80,60 @@ def generate_enum_string(enums):
else:
tag=""
data.append(f'py::enum_<slsDetectorDefs::{key}>(Defs, "{key}"{tag})\n')
operators = []
for v in value:
if "operator" not in v:
data.append(f'\t.value("{v}", slsDetectorDefs::{key}::{v})\n')
data.append('.export_values();\n\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()

View File

@ -2229,7 +2229,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.
@ -2349,6 +2349,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
"""

View File

@ -1086,6 +1086,16 @@ void init_det(py::module &m) {
(void (Detector::*)(const bool, sls::Positions)) &
Detector::setVeto,
py::arg(), py::arg() = Positions{})
.def("getVetoStream",
(Result<defs::EthernetInterface>(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<int>(Detector::*)(const int, const int, sls::Positions)
const) &

View File

@ -288,4 +288,20 @@ void init_enums(py::module &m) {
.value("TOP", slsDetectorDefs::portPosition::TOP)
.value("BOTTOM", slsDetectorDefs::portPosition::BOTTOM)
.export_values();
py::enum_<slsDetectorDefs::EthernetInterface>(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<const slsDetectorDefs::EthernetInterface &,
const slsDetectorDefs::EthernetInterface &>(
&operator|))
.def("__and__",
py::overload_cast<const slsDetectorDefs::EthernetInterface &,
const slsDetectorDefs::EthernetInterface &>(
&operator&));
}

View File

@ -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)
/** 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

View File

@ -989,7 +989,7 @@ int setExpTime(int64_t val) {
return FAIL;
}
LOG(logINFO, ("Setting exptime %lld ns\n", val));
val *= (1E-9 * systemFrequency);
val = (val * 1E-9 * systemFrequency) + 0.5;
set64BitReg(val, ASIC_INT_EXPTIME_LSB_REG, ASIC_INT_EXPTIME_MSB_REG);
// validate for tolerance
@ -1014,7 +1014,7 @@ int setPeriod(int64_t val) {
// continuous
if (burstMode == CONTINUOUS_INTERNAL || burstMode == CONTINUOUS_EXTERNAL) {
LOG(logINFO, ("Setting period %lld ns [Continuous mode]\n", val));
val *= (1E-9 * systemFrequency);
val = (val * 1E-9 * systemFrequency) + 0.5;
// trigger
if (getTiming() == TRIGGER_EXPOSURE) {
LOG(logINFO,
@ -1029,7 +1029,7 @@ int setPeriod(int64_t val) {
// burst
else {
LOG(logINFO, ("Setting period %lld ns [Burst mode]\n", val));
val *= (1E-9 * systemFrequency);
val = (val * 1E-9 * systemFrequency) + 0.5;
set64BitReg(val, ASIC_INT_PERIOD_LSB_REG, ASIC_INT_PERIOD_MSB_REG);
}
periodReg = val;
@ -1067,7 +1067,7 @@ int setDelayAfterTrigger(int64_t val) {
return FAIL;
}
LOG(logINFO, ("Setting delay after trigger %lld ns\n", val));
val *= (1E-9 * systemFrequency);
val = (val * 1E-9 * systemFrequency) + 0.5;
delayReg = val;
if (getTiming() == AUTO_TIMING) {
LOG(logINFO, ("\tAuto mode (not writing to register)\n"));
@ -1097,7 +1097,7 @@ int setBurstPeriod(int64_t val) {
return FAIL;
}
LOG(logINFO, ("Setting burst period %lld ns\n", val));
val *= (1E-9 * systemFrequency);
val = (val * 1E-9 * systemFrequency) + 0.5;
burstPeriodReg = val;
// burst and auto
@ -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));

View File

@ -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)

View File

@ -1832,6 +1832,8 @@ int stopStateMachine() {
bus_w(CONTROL_REG, bus_r(CONTROL_REG) & ~CONTROL_STOP_ACQ_MSK);
LOG(logINFO, ("Status Register: %08x\n", bus_r(STATUS_REG)));
resetCore();
return OK;
}

View File

@ -530,6 +530,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

View File

@ -249,3 +249,5 @@ int set_gain_caps(int);
int get_gain_caps(int);
int get_datastream(int);
int set_datastream(int);
int get_veto_stream(int);
int set_veto_stream(int);

View File

@ -375,6 +375,8 @@ void function_table() {
flist[F_GET_GAIN_CAPS] = &get_gain_caps;
flist[F_GET_DATASTREAM] = &get_datastream;
flist[F_SET_DATASTREAM] = &set_datastream;
flist[F_GET_VETO_STREAM] = &get_veto_stream;
flist[F_SET_VETO_STREAM] = &set_veto_stream;
// check
if (NUM_DET_FUNCTIONS >= RECEIVER_ENUM_START) {
@ -4107,7 +4109,8 @@ int software_trigger(int file_des) {
#else
if (arg && myDetectorType == MYTHEN3) {
ret = FAIL;
strcpy(mess, "Blocking trigger not implemented for Mythen3. Please use non blocking trigger.\n");
strcpy(mess, "Blocking trigger not implemented for Mythen3. Please use "
"non blocking trigger.\n");
LOG(logERROR, (mess));
}
// only set
@ -7508,29 +7511,10 @@ int set_veto(int file_des) {
// only set
if (Server_VerifyLock() == OK) {
setVeto(arg);
// if numinterfaces is 2 and veto is 1 now, then configuremac
if (arg > 0 && getNumberofUDPInterfaces() == 2 &&
is_udp_configured() == OK) {
ret = configureMAC();
if (ret != OK) {
sprintf(mess, "Configure Mac failed after enabling veto\n");
strcpy(configureMessage, mess);
LOG(logERROR, (mess));
configured = FAIL;
LOG(logWARNING, ("Configure FAIL, not all parameters "
"configured yet\n"));
} else {
LOG(logINFOGREEN, ("\tConfigure MAC successful\n"));
configured = OK;
}
}
if (ret == OK) {
int retval = getVeto();
LOG(logDEBUG1, ("veto mode retval: %u\n", retval));
validate(&ret, mess, arg, retval, "set veto mode", DEC);
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
@ -8229,13 +8213,8 @@ int set_gain_caps(int file_des) {
int get_gain_caps(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, ("Getting gain caps\n"));
int retval = -1;
LOG(logINFO, ("Getting gain caps\n"));
#ifndef MYTHEN3D
functionNotImplemented();
@ -8264,9 +8243,9 @@ int get_datastream(int file_des) {
// get only
if (arg != LEFT && arg != RIGHT) {
ret = FAIL;
sprintf(
mess,
"Could not get data stream enable. Invalid port position %d. Only left and right allowed\n",
sprintf(mess,
"Could not get data stream enable. Invalid port position %d. "
"Only left and right allowed\n",
arg);
LOG(logERROR, (mess));
} else {
@ -8307,7 +8286,8 @@ int set_datastream(int file_des) {
if (port != LEFT && port != RIGHT) {
ret = FAIL;
sprintf(mess,
"Could not %s. Invalid port position %d. Only left and right allowed\n",
"Could not %s. Invalid port position %d. Only left and "
"right allowed\n",
msg, port);
LOG(logERROR, (mess));
} else if (enable != 0 && enable != 1) {
@ -8335,3 +8315,52 @@ int set_datastream(int file_des) {
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}
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(&ret, mess, arg, retval, "set veto stream", DEC);
}
}
#endif
return Server_SendResult(file_des, INT32, NULL, 0);
}

View File

@ -1259,9 +1259,21 @@ class Detector {
/** [Gotthard2] */
Result<bool> getVeto(Positions pos = {}) const;
/** [Gotthard2] Default disabled */
/** [Gotthard2] Veto data in chip, Default disabled */
void setVeto(const bool enable, Positions pos = {});
/** [Gotthard2] */
Result<defs::EthernetInterface> 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<int> getADCConfiguration(const int chipIndex, const int adcIndex,
Positions pos = {}) const;
@ -1752,6 +1764,8 @@ class Detector {
private:
std::vector<int> getPortNumbers(int start_port);
void updateRxRateCorrections();
void setNumberofUDPInterfaces_(int n, Positions pos);
Result<int> getNumberofUDPInterfaces_(Positions pos) const;
};
} // namespace sls

View File

@ -1865,6 +1865,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<int>{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<defs::EthernetInterface>(arg);
interface = interface | (StringTo<defs::EthernetInterface>(arg));
}
det->setVetoStream(interface, std::vector<int>{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 << ' ';

View File

@ -945,6 +945,7 @@ class CmdProxy {
{"currentsource", &CmdProxy::currentsource},
{"timingsource", &CmdProxy::timingsource},
{"veto", &CmdProxy::veto},
{"vetostream", &CmdProxy::VetoStreaming},
{"confadc", &CmdProxy::ConfigureADC},
{"badchannels", &CmdProxy::BadChannels},
@ -1123,6 +1124,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 */
@ -1472,13 +1474,11 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID(
numinterfaces, getNumberofUDPInterfaces, setNumberofUDPInterfaces,
StringTo<int>,
"[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,
@ -1901,7 +1901,7 @@ class CmdProxy {
INTEGER_COMMAND_VEC_ID(veto, getVeto, setVeto, StringTo<int>,
"[0, 1]\n\t[Gotthard2] Enable or disable veto data "
"streaming from detector. Default is 0.");
"data from chip. Default is 0.");
/* Mythen3 Specific */

View File

@ -749,10 +749,28 @@ Result<std::string> Detector::getScanErrorMessage(Positions pos) const {
// Network Configuration (Detector<->Receiver)
Result<int> 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<int> 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;
@ -1560,6 +1578,41 @@ void Detector::setVeto(bool enable, Positions pos) {
pimpl->Parallel(&Module::setVeto, pos, enable);
}
Result<defs::EthernetInterface> 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<defs::EthernetInterface> 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::I10GBE)
? 2
: 1);
if (numinterfaces != old_numinterfaces) {
setNumberofUDPInterfaces_(numinterfaces, pos);
}
}
Result<int> Detector::getADCConfiguration(const int chipIndex,
const int adcIndex,
Positions pos) const {

View File

@ -1887,6 +1887,14 @@ void Module::setVeto(bool enable) {
sendToDetector(F_SET_VETO, static_cast<int>(enable), nullptr);
}
bool Module::getVetoStream() const {
return (sendToDetector<int>(F_GET_VETO_STREAM));
}
void Module::setVetoStream(const bool value) {
sendToDetector(F_SET_VETO_STREAM, static_cast<int>(value), nullptr);
}
int Module::getADCConfiguration(const int chipIndex, const int adcIndex) const {
int args[]{chipIndex, adcIndex};
return sendToDetector<int>(F_GET_ADC_CONFIGURATION, args);

View File

@ -408,6 +408,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);

View File

@ -15,6 +15,93 @@ using sls::Detector;
using test::GET;
using test::PUT;
// time specific measurements for gotthard2
TEST_CASE("timegotthard2", "[.cmd]") {
Detector det;
CmdProxy proxy(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::GOTTHARD2) {
// exptime
auto prev_val = det.getExptime();
{
std::ostringstream oss;
proxy.Call("exptime", {"220ns"}, -1, PUT, oss);
REQUIRE(oss.str() == "exptime 220ns\n");
}
{
std::ostringstream oss;
proxy.Call("exptime", {}, -1, GET, oss);
REQUIRE(oss.str() == "exptime 222ns\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setExptime(prev_val[i], {i});
}
// burst period
prev_val = det.getBurstPeriod();
{
std::ostringstream oss;
proxy.Call("burstperiod", {"220ns"}, -1, PUT, oss);
REQUIRE(oss.str() == "burstperiod 220ns\n");
}
{
std::ostringstream oss;
proxy.Call("burstperiod", {}, -1, GET, oss);
REQUIRE(oss.str() == "burstperiod 222ns\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setBurstPeriod(prev_val[i], {i});
}
// delay after trigger
prev_val = det.getDelayAfterTrigger();
{
std::ostringstream oss;
proxy.Call("delay", {"220ns"}, -1, PUT, oss);
REQUIRE(oss.str() == "delay 220ns\n");
}
{
std::ostringstream oss;
proxy.Call("delay", {}, -1, GET, oss);
REQUIRE(oss.str() == "delay 222ns\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setDelayAfterTrigger(prev_val[i], {i});
}
// period in burst mode
auto burst_prev_val = det.getBurstMode();
det.setBurstMode(defs::BURST_INTERNAL, {});
prev_val = det.getPeriod();
{
std::ostringstream oss;
proxy.Call("period", {"220ns"}, -1, PUT, oss);
REQUIRE(oss.str() == "period 220ns\n");
}
{
std::ostringstream oss;
proxy.Call("period", {}, -1, GET, oss);
REQUIRE(oss.str() == "period 222ns\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setPeriod(prev_val[i], {i});
}
// period in continuous mode
det.setBurstMode(defs::CONTINUOUS_INTERNAL, {});
prev_val = det.getPeriod();
{
std::ostringstream oss;
proxy.Call("period", {"220ns"}, -1, PUT, oss);
REQUIRE(oss.str() == "period 220ns\n");
}
{
std::ostringstream oss;
proxy.Call("period", {}, -1, GET, oss);
REQUIRE(oss.str() == "period 222ns\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setPeriod(prev_val[i], {i});
det.setBurstMode(burst_prev_val[i], {i});
}
}
}
/* dacs */
TEST_CASE("Setting and reading back GOTTHARD2 dacs", "[.cmd][.dacs]") {
@ -552,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);

View File

@ -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);

View File

@ -1790,39 +1790,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);

View File

@ -38,6 +38,7 @@ std::string ToString(const defs::burstMode s);
std::string ToString(const defs::timingSourceType s);
std::string ToString(const defs::M3_GainCaps s);
std::string ToString(const defs::portPosition 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);
@ -301,6 +302,7 @@ template <> defs::burstMode StringTo(const std::string &s);
template <> defs::timingSourceType StringTo(const std::string &s);
template <> defs::M3_GainCaps StringTo(const std::string &s);
template <> defs::portPosition 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);

View File

@ -403,6 +403,17 @@ typedef struct {
enum portPosition { LEFT, RIGHT, TOP, BOTTOM };
#ifdef __cplusplus
enum class EthernetInterface {
#else
enum EthernetInterface {
#endif
NONE = 0,
I3GBE = 1 << 1,
I10GBE = 1 << 2,
ALL = I3GBE | I10GBE
};
#ifdef __cplusplus
/** scan structure */
@ -496,8 +507,18 @@ typedef struct {
#ifdef __cplusplus
};
inline slsDetectorDefs::EthernetInterface
operator|( const slsDetectorDefs::EthernetInterface &a,
const slsDetectorDefs::EthernetInterface &b) {
return slsDetectorDefs::EthernetInterface(static_cast<int32_t>(a) |
static_cast<int32_t>(b));
};
inline slsDetectorDefs::EthernetInterface operator&( const slsDetectorDefs::EthernetInterface &a,
const slsDetectorDefs::EthernetInterface &b) {
return slsDetectorDefs::EthernetInterface(static_cast<int32_t>(a) & static_cast<int32_t>(b));
};
#endif
;
#ifdef __cplusplus
struct detParameters {
@ -644,3 +665,4 @@ using Positions = const std::vector<int> &;
using defs = slsDetectorDefs;
} // namespace sls
#endif

View File

@ -226,6 +226,8 @@ enum detFuncs {
F_GET_GAIN_CAPS,
F_GET_DATASTREAM,
F_SET_DATASTREAM,
F_GET_VETO_STREAM,
F_SET_VETO_STREAM,
NUM_DET_FUNCTIONS,
RECEIVER_ENUM_START = 256, /**< detector function should not exceed this
@ -554,8 +556,12 @@ 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_SET_GAIN_CAPS: return "F_SET_GAIN_CAPS";
case F_GET_GAIN_CAPS: return "F_GET_GAIN_CAPS";
case F_GET_DATASTREAM: return "F_GET_DATASTREAM";
case F_SET_DATASTREAM: return "F_SET_DATASTREAM";
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";

View File

@ -5,9 +5,8 @@
#define APIGUI 0x210225
#define APICTB 0x210621
#define APIGOTTHARD 0x210621
#define APIGOTTHARD2 0x210621
#define APIJUNGFRAU 0x210621
#define APIGOTTHARD2 0x210715
#define APIJUNGFRAU 0x210714
#define APIMYTHEN3 0x210621
#define APIMOENCH 0x210621
#define APIEIGER 0x210721

View File

@ -555,6 +555,25 @@ std::string ToString(const defs::portPosition 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) {
@ -923,6 +942,19 @@ template <> defs::portPosition StringTo(const std::string &s) {
throw sls::RuntimeError("Unknown port position " + 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);

View File

@ -5,6 +5,7 @@
#include <thread>
#include <future>
#include <iostream>
#include <thread>
std::vector<char> server() {
std::cout << "starting server\n";

View File

@ -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 <array>
#include <map>
#include <sstream>
@ -322,5 +322,12 @@ TEST_CASE("Print a member of patternParameters"){
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");
}