Program Listing for File config_register.cpp
↰ Return to documentation for file (config/config_register.cpp)
#include "felixtag.h"
#include "felix/felix_fid.h"
#include "felix/felix_ports.h"
#include "felix/felix_client_util.hpp"
#include "config_register.hpp"
#include <cstdint>
#include <format>
#include <string>
std::string ConfigRegister::usage() {
return
R"(felix-register - Receive control data for registers and reply.
Usage:
felix-register [options] <local_ip_or_interface> (<device> <did> <cid>)...
)";
}
std::string ConfigRegister::bugs() {
return
R"(
Report bugs to <https://its.cern.ch/jira/projects/FLXUSERS>.
)";
}
std::string ConfigRegister::options() {
return
std::format(R"(
Options:
-h --help Show this screen.
--version Show version.
--bus-dir=<bus-directory> Set bus directory [default: bus]
--bus-groupname=<groupname> Set groupname for bus to use [default: FELIX]
--cmd-port=<N> Set port number for commands to the devices [default: {} + (10 * first-device)]
--pub-port=<N> Set port number for publications from the devices [default: {} + (10 * first-device)]
--log-level=<loglevel> Specify level of logging (trace, debug, info, notice, warning, error, fatal) [default: info]
--mon-port=<N> Set port number for monitoring of the devices [default: {} + (10 * first-device)]
--mon-interval=<seconds> Set monitoring interval [default: 5]
--mon-regfile=<file> File containing the name of additinal card registers to monitor [default: ""]
--verbose Show verbose output [default: false]
--verbose-bus Show bus information [default: false]
--no-cmd-channel Do not instantiate a Cmd channel, for testing only [default: false]
--no-reply Do not reply, for unit tests only [default: false]
--no-mon-channel Do not start MON channel [default: false]
Arguments:
<local_ip_or_interface> Local IP or interface
<device> Use FLX device
<did> DID (Detector Id) to use in FID (Felix ID)
<cid> CID (Connector Id) to use in FID (Felix ID)
Notes:
<device> <did> <cid> triplets should be declared in endpoint-0, endpoint-1 order.
Requests for non-existing endpoint-1 will be routed to endpoint-0: device 1 -> device 0, device 3 -> device 2
)", PORT_COMMAND_OFFSET, PORT_REPLY_OFFSET, PORT_MON_OFFSET);
}
void ConfigRegister::parse(int argc, char **argv) {
std::map<std::string, docopt::value> args
= docopt::docopt(usage() + options() + bugs(),
{ argv + 1, argv + argc },
true, // show help if requested
(std::string(argv[0]) + " " + FELIX_TAG).c_str()); // version string
local_ip = get_value_from_getifaddrs(args["<local_ip_or_interface>"].asString(), true);
bus_dir = args["--bus-dir"].asString();
bus_group = args["--bus-groupname"].asString();
verbose = args["--verbose"].asBool();
verbose_bus = args["--verbose-bus"].asBool();
mon_interval = static_cast<unsigned int>(args["--mon-interval"].asLong());
if (args["--mon-regfile"].asString() != ""){
extra_mon = args["--mon-regfile"].asString();
}
enable_cmd = not args["--no-cmd-channel"].asBool();
enable_reply = not args["--no-reply"].asBool();
enable_mon = not args["--no-mon-channel"].asBool();
unsigned int cmd_port_offset = std::stoul(args["--cmd-port"].asString(), nullptr, 0);
unsigned int reply_port_offset = std::stoul(args["--pub-port"].asString(), nullptr, 0);
unsigned int mon_port_offset = std::stoul(args["--mon-port"].asString(), nullptr, 0);
auto devices = args["<device>"].asStringList();
auto dids = args["<did>"].asStringList();
auto cids = args["<cid>"].asStringList();
constexpr uint8_t sid = 0;
constexpr uint8_t virt = 1;
int d0 = std::stoi(devices.at(0));
int first_did = std::stoi(dids.at(0), nullptr, 0);
int first_cid = std::stoi(cids.at(0), nullptr, 0);
//use first did and cid for monitoring e-link
fid_mon = get_fid_from_ids(first_did, first_cid, MON_LINK, sid, FID_VERSION_ID, 0, virt); // to_flx = 0
//use first device number for the port
port_mon = static_cast<int>(mon_port_offset + 10*d0);
for (unsigned int d = 0; d < args["<device>"].asStringList().size(); ++d){
int did = std::stoi(dids[d], nullptr, 0);
int cid = std::stoi(cids[d], nullptr, 0);
int dev = std::stoi(devices.at(d), nullptr, 0);
RegisterDeviceConfig c {
.dev_no = dev,
.did = did,
.cid = cid,
.port_cmd = static_cast<int>(cmd_port_offset + 10*dev),
.port_reply = static_cast<int>(reply_port_offset + 10*dev),
.fid_cmd = get_fid_from_ids(did, cid, COMMAND_REPLY_LINK, sid, FID_VERSION_ID, 1, virt), // to_flx = 1
.fid_reply = get_fid_from_ids(did, cid, COMMAND_REPLY_LINK, sid, FID_VERSION_ID, 0, virt), // to_flx = 0
};
dconfs.push_back(c);
}
}