This commit is contained in:
maliakal_d 2021-07-15 13:44:42 +02:00
parent a127f8c97a
commit 8354395f64
14 changed files with 216 additions and 42 deletions

View File

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

View File

@ -36,6 +36,7 @@
/** 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

View File

@ -1,7 +1,7 @@
#pragma once
#include "sls/sls_detector_defs.h"
#define REQRD_FRMWRE_VRSN (0x210714)
#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

@ -7525,7 +7525,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 +7567,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;

View File

@ -1244,9 +1244,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;
@ -1727,6 +1739,7 @@ class Detector {
private:
std::vector<int> getPortNumbers(int start_port);
void updateRxRateCorrections();
defs::EthernetInterface in_{defs::NONE};
};
} // namespace sls

View File

@ -1802,6 +1802,49 @@ 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: " +
arg);
}
break;
}
interface = interface | (StringTo<defs::EthernetInterface>(arg));
}
det->setVetoStream(interface, std::vector<int>{det_id});
os << ToString(args) << '\n';
} else {
throw sls::RuntimeError("Unknown action");
}
return os.str();
}
std::string CmdProxy::ConfigureADC(int action) {
std::ostringstream os;
os << cmd << ' ';

View File

@ -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<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,
@ -1913,7 +1913,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

@ -1547,6 +1547,16 @@ void Detector::setVeto(bool enable, Positions pos) {
pimpl->Parallel(&Module::setVeto, pos, enable);
}
Result<defs::EthernetInterface> Detector::getVetoStream(Positions pos) const {
// return pimpl->Parallel(&Module::getVetoStream, pos);
return Result<defs::EthernetInterface> res{in_};
}
void Detector::setVetoStream(defs::EthernetInterface interface, Positions pos) {
// pimpl->Parallel(&Module::setVetoStream, pos, enable);
in_ = interface;
}
Result<int> Detector::getADCConfiguration(const int chipIndex,
const int adcIndex,
Positions pos) const {

View File

@ -552,6 +552,36 @@ 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.getNumberofUDPInterfaces().tsquash(
// "inconsistent numinterfaces to test");
/* {
std::ostringstream oss;
proxy.Call("vetostream", {"sdf"}, -1, PUT, oss);
REQUIRE(oss.str() == "vetostream 2\n");
}
{
std::ostringstream oss;
proxy.Call("vetostream", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "vetostream 1\n");
}
{
std::ostringstream oss;
proxy.Call("vetostream", {}, -1, GET, oss);
REQUIRE(oss.str() == "vetostream 1\n");
}*/
// det.setNumberofUDPInterfaces(prev_val);
} else {
REQUIRE_THROWS(proxy.Call("vetostream", {}, -1, GET));
REQUIRE_THROWS(proxy.Call("vetostream", {"1"}, -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

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

View File

@ -36,6 +36,7 @@ std::string ToString(const defs::dacIndex s);
std::string ToString(const std::vector<defs::dacIndex> &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);

View File

@ -394,6 +394,29 @@ typedef struct {
*/
enum timingSourceType { TIMING_INTERNAL, TIMING_EXTERNAL };
#ifdef __cplusplus
enum class EthernetInterface : int32_t {
#else
enum EthernetInterface {
#endif
NONE = 0,
I3GBE = 1 << 1,
I10GBE = 1 << 2,
ALL = I3GBE | I10GBE
};
#ifdef __cplusplus
inline EthernetInterface operator|(EthernetInterface a,
EthernetInterface b) {
return EthernetInterface(static_cast<int32_t>(a) |
static_cast<int32_t>(b));
}
inline bool operator&(EthernetInterface a, EthernetInterface b) {
return (static_cast<int32_t>(a) & static_cast<int32_t>(b));
}
#endif
#ifdef __cplusplus
/** scan structure */

View File

@ -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::NONE:
return std::string("none");
default:
if (s & defs::I3GBE)
os << "3gbe, ";
if (s & defs::I10GBE)
os << "10gbe, ";
auto rs = os.str();
rs.erase(rs.end() - 2);
return rs;
}
}
const std::string &ToString(const std::string &s) { return s; }
template <> defs::detectorType StringTo(const std::string &s) {
@ -859,6 +876,18 @@ 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;
rs.erase(rs.find(','));
if (rs == "none")
return defs::NONE;
if (rs == "3gbe")
return defs::I3GBE;
if (rs == "10gbe")
return defs::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);