Line data Source code
1 : /**
2 : * @file EndpointNode.cpp
3 : *
4 : * This is part of the DUNE DAQ Software Suite, copyright 2020.
5 : * Licensing/copyright details are in the COPYING file that you should have
6 : * received with this code.
7 : */
8 :
9 : #include "timing/EndpointNode.hpp"
10 : #include "timing/toolbox.hpp"
11 :
12 : #include "logging/Logging.hpp"
13 :
14 : #include <string>
15 : #include <utility>
16 : #include <vector>
17 :
18 : namespace dunedaq {
19 : namespace timing {
20 :
21 0 : UHAL_REGISTER_DERIVED_NODE(EndpointNode)
22 :
23 : //-----------------------------------------------------------------------------
24 0 : EndpointNode::EndpointNode(const uhal::Node& node)
25 0 : : EndpointNodeInterface(node)
26 0 : {}
27 : //-----------------------------------------------------------------------------
28 :
29 : //-----------------------------------------------------------------------------
30 0 : EndpointNode::~EndpointNode() {}
31 : //-----------------------------------------------------------------------------
32 :
33 : //-----------------------------------------------------------------------------
34 : void
35 0 : EndpointNode::enable(uint32_t address, uint32_t /*partition*/) const // NOLINT(build/unsigned)
36 : {
37 0 : getNode("csr.ctrl.addr").write(address);
38 :
39 0 : getNode("csr.ctrl.ep_en").write(0x1);
40 0 : getClient().dispatch();
41 :
42 0 : auto start = std::chrono::high_resolution_clock::now();
43 :
44 0 : std::chrono::milliseconds ms_since_start(0);
45 :
46 0 : uhal::ValWord<uint32_t> counters_ready;
47 :
48 : // Wait for the endpoint to be happy
49 0 : while (ms_since_start.count() < 500) {
50 0 : auto now = std::chrono::high_resolution_clock::now();
51 0 : ms_since_start = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
52 :
53 0 : millisleep(10);
54 :
55 0 : counters_ready = getNode("csr.stat.ctrs_rdy").read();
56 0 : getClient().dispatch();
57 0 : TLOG_DEBUG(1) << "counters_ready: 0x" << std::hex << counters_ready.value();
58 :
59 0 : if (counters_ready) {
60 0 : TLOG_DEBUG(1) << "counters ready";
61 0 : break;
62 : }
63 : }
64 :
65 0 : if (!counters_ready) {
66 0 : ers::warning(EndpointBroadcastMessageCountersNotReady(ERS_HERE));
67 : }
68 0 : }
69 : //-----------------------------------------------------------------------------
70 :
71 : //-----------------------------------------------------------------------------
72 : void
73 0 : EndpointNode::disable() const
74 : {
75 0 : getNode("csr.ctrl.ep_en").write(0x0);
76 : // getNode("csr.ctrl.buf_en").write(0x0);
77 0 : getClient().dispatch();
78 0 : }
79 : //-----------------------------------------------------------------------------
80 :
81 : //-----------------------------------------------------------------------------
82 : void
83 0 : EndpointNode::reset(uint32_t address, uint32_t /*partition*/) const // NOLINT(build/unsigned)
84 : {
85 :
86 0 : getNode("csr.ctrl.ep_en").write(0x0);
87 0 : getNode("csr.ctrl.ctr_rst").write(0x1);
88 0 : getNode("csr.ctrl.ctr_rst").write(0x0);
89 0 : getClient().dispatch();
90 :
91 : //getNode("csr.ctrl.buf_en").write(0x0);
92 :
93 0 : enable(address);
94 0 : }
95 : //-----------------------------------------------------------------------------
96 :
97 : //-----------------------------------------------------------------------------
98 : std::string
99 0 : EndpointNode::get_status(bool print_out) const
100 : {
101 :
102 0 : std::stringstream status;
103 :
104 0 : std::vector<std::pair<std::string, std::string>> ept_summary;
105 :
106 0 : auto ept_timestamp = getNode("tstamp").readBlock(2);
107 0 : auto ept_control = read_sub_nodes(getNode("csr.ctrl"), false);
108 0 : auto ept_state = read_sub_nodes(getNode("csr.stat"), false);
109 0 : getNode("cmd_ctrs.addr").write(0x0);
110 0 : auto counters = getNode("cmd_ctrs.data").readBlock(0xff);
111 0 : getClient().dispatch();
112 :
113 0 : ept_summary.push_back(std::make_pair("Enabled", std::to_string(ept_control.find("ep_en")->second.value())));
114 0 : ept_summary.push_back(std::make_pair("Address", std::to_string(ept_control.find("addr")->second.value())));
115 0 : ept_summary.push_back(std::make_pair("State", get_endpoint_state_map().at(ept_state.find("ep_stat")->second.value())));
116 0 : ept_summary.push_back(std::make_pair("Timestamp (hex)", format_reg_value(tstamp2int(ept_timestamp))));
117 0 : ept_summary.push_back(std::make_pair("Timestamp", format_timestamp(ept_timestamp,62500000)));
118 :
119 0 : status << std::endl << format_reg_table(ept_summary, "Endpoint summary", { "", "" }) << std::endl;
120 : // status << "Endpoint frequency: " << ept_clock_frequency << " MHz" << std::endl;
121 0 : status << format_reg_table(ept_state, "Endpoint state") << std::endl;
122 :
123 0 : std::vector<uint32_t> non_zero_counters;
124 0 : std::vector<std::string> counter_labels;
125 :
126 0 : for (uint i=0; i < counters.size(); ++i)
127 : {
128 0 : auto counter = counters.at(i);
129 0 : if (counter > 0)
130 : {
131 0 : counter_labels.push_back(format_reg_value(i));
132 0 : non_zero_counters.push_back(counter);
133 : }
134 : }
135 0 : std::vector<std::vector<uint32_t>> counters_container = { non_zero_counters }; // NOLINT(build/unsigned)
136 :
137 0 : status << format_counters_table(counters_container, { "Received cmd counters" }, "Endpoint cmd counters (>0)", counter_labels);
138 0 : status << std::endl;
139 :
140 0 : if (print_out)
141 0 : TLOG() << status.str();
142 0 : return status.str();
143 0 : }
144 : //-----------------------------------------------------------------------------
145 :
146 : //-----------------------------------------------------------------------------
147 : uint64_t // NOLINT(build/unsigned)
148 0 : EndpointNode::read_timestamp() const
149 : {
150 0 : auto timestamp = getNode("tstamp").readBlock(2);
151 0 : getClient().dispatch();
152 0 : return tstamp2int(timestamp);
153 0 : }
154 : //-----------------------------------------------------------------------------
155 :
156 : //-----------------------------------------------------------------------------
157 : void
158 0 : EndpointNode::get_info(timingendpointinfo::TimingEndpointInfo& mon_data) const
159 : {
160 0 : auto timestamp = getNode("tstamp").readBlock(2);
161 0 : auto endpoint_control = read_sub_nodes(getNode("csr.ctrl"), false);
162 0 : auto endpoint_state = read_sub_nodes(getNode("csr.stat"), false);
163 0 : getClient().dispatch();
164 :
165 0 : mon_data.state = endpoint_state.at("ep_stat").value();
166 0 : mon_data.ready = endpoint_state.at("ep_rdy").value();
167 0 : mon_data.address = endpoint_control.at("addr").value();
168 0 : mon_data.timestamp = tstamp2int(timestamp);
169 0 : mon_data.sfp_tx_disable = !endpoint_state.at("ep_txen").value();
170 0 : }
171 : //-----------------------------------------------------------------------------
172 :
173 : } // namespace timing
174 : } // namespace dunedaq
|