Line data Source code
1 : #include "felixtag.h"
2 : #include "felix/felix_fid.h"
3 : #include "felix/felix_ports.h"
4 : #include "felix/felix_client_util.hpp"
5 : #include "config_register.hpp"
6 :
7 : #include <cstdint>
8 : #include <format>
9 : #include <string>
10 :
11 0 : std::string ConfigRegister::usage() {
12 0 : return
13 0 : R"(felix-register - Receive control data for registers and reply.
14 :
15 : Usage:
16 : felix-register [options] <local_ip_or_interface> (<device> <did> <cid>)...
17 : )";
18 : }
19 :
20 :
21 0 : std::string ConfigRegister::bugs() {
22 0 : return
23 0 : R"(
24 : Report bugs to <https://its.cern.ch/jira/projects/FLXUSERS>.
25 : )";
26 : }
27 :
28 :
29 0 : std::string ConfigRegister::options() {
30 0 : return
31 : std::format(R"(
32 : Options:
33 : -h --help Show this screen.
34 : --version Show version.
35 : --bus-dir=<bus-directory> Set bus directory [default: bus]
36 : --bus-groupname=<groupname> Set groupname for bus to use [default: FELIX]
37 : --cmd-port=<N> Set port number for commands to the devices [default: {} + (10 * first-device)]
38 : --pub-port=<N> Set port number for publications from the devices [default: {} + (10 * first-device)]
39 : --log-level=<loglevel> Specify level of logging (trace, debug, info, notice, warning, error, fatal) [default: info]
40 : --mon-port=<N> Set port number for monitoring of the devices [default: {} + (10 * first-device)]
41 : --mon-interval=<seconds> Set monitoring interval [default: 5]
42 : --mon-regfile=<file> File containing the name of additinal card registers to monitor [default: ""]
43 : --verbose Show verbose output [default: false]
44 : --verbose-bus Show bus information [default: false]
45 : --no-cmd-channel Do not instantiate a Cmd channel, for testing only [default: false]
46 : --no-reply Do not reply, for unit tests only [default: false]
47 : --no-mon-channel Do not start MON channel [default: false]
48 :
49 : Arguments:
50 : <local_ip_or_interface> Local IP or interface
51 : <device> Use FLX device
52 : <did> DID (Detector Id) to use in FID (Felix ID)
53 : <cid> CID (Connector Id) to use in FID (Felix ID)
54 :
55 : Notes:
56 : <device> <did> <cid> triplets should be declared in endpoint-0, endpoint-1 order.
57 : Requests for non-existing endpoint-1 will be routed to endpoint-0: device 1 -> device 0, device 3 -> device 2
58 0 : )", PORT_COMMAND_OFFSET, PORT_REPLY_OFFSET, PORT_MON_OFFSET);
59 : }
60 :
61 :
62 0 : void ConfigRegister::parse(int argc, char **argv) {
63 :
64 0 : std::map<std::string, docopt::value> args
65 0 : = docopt::docopt(usage() + options() + bugs(),
66 0 : { argv + 1, argv + argc },
67 : true, // show help if requested
68 0 : (std::string(argv[0]) + " " + FELIX_TAG).c_str()); // version string
69 :
70 :
71 :
72 0 : local_ip = get_value_from_getifaddrs(args["<local_ip_or_interface>"].asString(), true);
73 0 : bus_dir = args["--bus-dir"].asString();
74 0 : bus_group = args["--bus-groupname"].asString();
75 0 : verbose = args["--verbose"].asBool();
76 0 : verbose_bus = args["--verbose-bus"].asBool();
77 0 : mon_interval = static_cast<unsigned int>(args["--mon-interval"].asLong());
78 0 : if (args["--mon-regfile"].asString() != ""){
79 0 : extra_mon = args["--mon-regfile"].asString();
80 : }
81 :
82 0 : enable_cmd = not args["--no-cmd-channel"].asBool();
83 0 : enable_reply = not args["--no-reply"].asBool();
84 0 : enable_mon = not args["--no-mon-channel"].asBool();
85 :
86 0 : unsigned int cmd_port_offset = std::stoul(args["--cmd-port"].asString(), nullptr, 0);
87 0 : unsigned int reply_port_offset = std::stoul(args["--pub-port"].asString(), nullptr, 0);
88 0 : unsigned int mon_port_offset = std::stoul(args["--mon-port"].asString(), nullptr, 0);
89 :
90 0 : auto devices = args["<device>"].asStringList();
91 0 : auto dids = args["<did>"].asStringList();
92 0 : auto cids = args["<cid>"].asStringList();
93 :
94 0 : constexpr uint8_t sid = 0;
95 0 : constexpr uint8_t virt = 1;
96 0 : int d0 = std::stoi(devices.at(0));
97 0 : int first_did = std::stoi(dids.at(0), nullptr, 0);
98 0 : int first_cid = std::stoi(cids.at(0), nullptr, 0);
99 : //use first did and cid for monitoring e-link
100 0 : fid_mon = get_fid_from_ids(first_did, first_cid, MON_LINK, sid, FID_VERSION_ID, 0, virt); // to_flx = 0
101 : //use first device number for the port
102 0 : port_mon = static_cast<int>(mon_port_offset + 10*d0);
103 :
104 0 : for (unsigned int d = 0; d < args["<device>"].asStringList().size(); ++d){
105 0 : int did = std::stoi(dids[d], nullptr, 0);
106 0 : int cid = std::stoi(cids[d], nullptr, 0);
107 0 : int dev = std::stoi(devices.at(d), nullptr, 0);
108 0 : RegisterDeviceConfig c {
109 : .dev_no = dev,
110 : .did = did,
111 : .cid = cid,
112 0 : .port_cmd = static_cast<int>(cmd_port_offset + 10*dev),
113 0 : .port_reply = static_cast<int>(reply_port_offset + 10*dev),
114 0 : .fid_cmd = get_fid_from_ids(did, cid, COMMAND_REPLY_LINK, sid, FID_VERSION_ID, 1, virt), // to_flx = 1
115 0 : .fid_reply = get_fid_from_ids(did, cid, COMMAND_REPLY_LINK, sid, FID_VERSION_ID, 0, virt), // to_flx = 0
116 0 : };
117 0 : dconfs.push_back(c);
118 : }
119 0 : }
|