DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
HermesCoreController.cpp
Go to the documentation of this file.
2
3#include <chrono> // std::chrono::seconds
4#include <thread> // std::this_thread::sleep_for
5#include <fmt/core.h>
6
7namespace dunedaq {
8namespace hermesmodules {
9
10//-----------------------------------------------------------------------------
11HermesCoreController::HermesCoreController(uhal::HwInterface hw, std::string readout_id) :
12 m_hw(hw), m_readout(m_hw.getNode(readout_id)) {
13
14 this->load_hw_info();
15
16}
17
18//-----------------------------------------------------------------------------
22
23//-----------------------------------------------------------------------------
24void
26
27 // Check magic number
28 auto magic = m_readout.getNode("info.magic").read();
29 m_readout.getClient().dispatch();
30 if (magic.value() != 0xdeadbeef){
31 // TODO: add ERS exception
32 throw MagicNumberError(ERS_HERE, magic.value(),0xdeadbeef);
33 }
34
35
36 auto design = m_readout.getNode("info.versions.design").read();
37 auto major = m_readout.getNode("info.versions.major").read();
38 auto minor = m_readout.getNode("info.versions.minor").read();
39 auto patch = m_readout.getNode("info.versions.patch").read();
40
41
42 auto n_mgt = m_readout.getNode("info.generics.n_mgts").read();
43 auto n_src = m_readout.getNode("info.generics.n_srcs").read();
44 auto ref_freq = m_readout.getNode("info.generics.ref_freq").read();
45 m_readout.getClient().dispatch();
46
47 // Version
48 m_core_info.design = design.value();
49 m_core_info.major = major.value();
50 m_core_info.minor = minor.value();
51 m_core_info.patch = patch.value();
52
53 // Generics
54 m_core_info.n_mgt = n_mgt.value();
55 m_core_info.n_src = n_src.value();
56 m_core_info.ref_freq = ref_freq.value();
57
58 // Extra info
60
61 fmt::print("Number of links: {}\n", m_core_info.n_mgt);
62 fmt::print("Number of sources: {}\n", m_core_info.n_src);
63 fmt::print("Reference freq: {}\n", m_core_info.ref_freq);
64}
65
66
67//-----------------------------------------------------------------------------
68void
70 if ( i >= m_core_info.n_mgt ) {
71 throw LinkDoesNotExist(ERS_HERE, i);
72 }
73
74 m_readout.getNode("tx_path.csr_tx_mux.ctrl.tx_mux_sel").write(i);
75 m_readout.getClient().dispatch();
76}
77
78
79//-----------------------------------------------------------------------------
80void
82 if ( i >= m_core_info.n_src ) {
83 throw InputBufferDoesNotExist(ERS_HERE, i);
84 }
85
86 m_readout.getNode("tx_path.tx_mux.csr.ctrl.sel_buf").write(i);
87 m_readout.getClient().dispatch();
88}
89
90
91//-----------------------------------------------------------------------------
92void
94 if ( i >= m_core_info.n_src ) {
95 throw InputBufferDoesNotExist(ERS_HERE, i);
96 }
97
98 m_readout.getNode("tx_path.csr_udp_core.ctrl.udp_core_sel").write(i);
99 m_readout.getClient().dispatch();
100}
101
102
103//-----------------------------------------------------------------------------
104void
106
107 if (nuke) {
108 m_readout.getNode("csr.ctrl.nuke").write(0x1);
109 m_readout.getClient().dispatch();
110
111 // time.sleep(0.1);
112 std::this_thread::sleep_for (std::chrono::milliseconds(1));
113
114 m_readout.getNode("csr.ctrl.nuke").write(0x0);
115 m_readout.getClient().dispatch();
116 }
117
118 m_readout.getNode("csr.ctrl.soft_rst").write(0x1);
119 m_readout.getClient().dispatch();
120
121 // time.sleep(0.1)
122 std::this_thread::sleep_for (std::chrono::milliseconds(1));
123
124
125 m_readout.getNode("csr.ctrl.soft_rst").write(0x0);
126 m_readout.getClient().dispatch();
127
128}
129
130
131//-----------------------------------------------------------------------------
132bool
133HermesCoreController::is_link_in_error(uint16_t link, bool do_throw) {
134
135 this->sel_tx_mux(link);
136
137 auto& tx_mux_stat = m_readout.getNode("tx_path.tx_mux.csr.stat");
138 auto err = tx_mux_stat.getNode("err").read();
139 auto eth_rdy = tx_mux_stat.getNode("eth_rdy").read();
140 auto src_rdy = tx_mux_stat.getNode("src_rdy").read();
141 auto udp_rdy = tx_mux_stat.getNode("udp_rdy").read();
142 tx_mux_stat.getClient().dispatch();
143
144 bool is_error = (err || !eth_rdy || !src_rdy || !udp_rdy);
145
146 if ( do_throw && is_error ) {
147 throw LinkInError(ERS_HERE, link, err, eth_rdy, src_rdy, udp_rdy);
148 }
149
150 return is_error;
151}
152
153//-----------------------------------------------------------------------------
154void
156
157 this->sel_tx_mux(link);
158
159 auto& tx_mux_ctrl = m_readout.getNode("tx_path.tx_mux.csr.ctrl");
160
161 // Not sure what to do with this
162 auto tx_en = tx_mux_ctrl.getNode("tx_en").read();
163 auto buf_en = tx_mux_ctrl.getNode("en_buf").read();
164 auto ctrl_en = tx_mux_ctrl.getNode("en").read();
165
166 if ( enable ) {
167
168 // Assume that all is off
169
170 // Enable the main logic
171 tx_mux_ctrl.getNode("en").write(0x1);
172 tx_mux_ctrl.getClient().dispatch();
173
174 // Enable transmitter first
175 tx_mux_ctrl.getNode("tx_en").write(0x1);
176 tx_mux_ctrl.getClient().dispatch();
177
178 // Enable buffers last
179 tx_mux_ctrl.getNode("en_buf").write(0x1);
180 tx_mux_ctrl.getClient().dispatch();
181
182
183 } else {
184
185 // Disable buffers last
186 tx_mux_ctrl.getNode("en_buf").write(0x0);
187 tx_mux_ctrl.getClient().dispatch();
188
189 // Disable transmitter first
190 tx_mux_ctrl.getNode("tx_en").write(0x0);
191 tx_mux_ctrl.getClient().dispatch();
192
193 // Disable the main logic
194 tx_mux_ctrl.getNode("en").write(0x0);
195 tx_mux_ctrl.getClient().dispatch();
196
197 }
198
199}
200
201
202//-----------------------------------------------------------------------------
203void
204HermesCoreController::config_mux(uint16_t link, uint16_t det, uint16_t crate, uint16_t slot) {
205 this->sel_tx_mux(link);
206
207
208 auto& mux_ctrl = m_readout.getNode("tx_path.tx_mux.mux.ctrl");
209
210 mux_ctrl.getNode("detid").write(det);
211 mux_ctrl.getNode("crate").write(crate);
212 mux_ctrl.getNode("slot").write(slot);
213 mux_ctrl.getClient().dispatch();
214
215}
216
217
218//-----------------------------------------------------------------------------
219void
220HermesCoreController::config_udp( uint16_t link, uint64_t src_mac, uint32_t src_ip, uint16_t src_port, uint64_t dst_mac, uint32_t dst_ip, uint16_t dst_port, uint32_t filters) {
221
222 if ( link >= m_core_info.n_mgt ) {
223 throw LinkDoesNotExist(ERS_HERE, link);
224 }
225
226 this->sel_udp_core(link);
227
228 // const std::string udp_ctrl_name = fmt::format("udp.udp_core_{}.udp_core_control.nz_rst_ctrl");
229 const auto& udp_ctrl = m_readout.getNode("tx_path.udp_core.udp_core_control");
230
231
232 udp_ctrl.getNode("src_addr_ctrl.use_external").write(0);
233
234 // Load the source mac address
235 udp_ctrl.getNode("src_addr_ctrl.src_mac_addr_lower").write(src_mac & 0xffffffff);
236 udp_ctrl.getNode("src_addr_ctrl.src_mac_addr_upper").write((src_mac >> 32) & 0xffff);
237
238 // Load the source ip address
239 udp_ctrl.getNode("src_addr_ctrl.src_ip_addr").write(src_ip);
240
241 // Load the dst mac address
242 udp_ctrl.getNode("ctrl.dst_mac_addr_lower").write(dst_mac & 0xffffffff);
243 udp_ctrl.getNode("ctrl.dst_mac_addr_upper").write((dst_mac >> 32) & 0xffff);
244
245 // Load the dst ip address
246 udp_ctrl.getNode("ctrl.dst_ip_addr").write(dst_ip);
247
248 // Ports
249 udp_ctrl.getNode("src_addr_ctrl.src_port").write(src_port);
250 udp_ctrl.getNode("ctrl.dst_port").write(dst_port);
251
252
253 udp_ctrl.getNode("ctrl.filter_control").write(filters);
254 udp_ctrl.getClient().dispatch();
255
256}
257
258//-----------------------------------------------------------------------------
259void
260HermesCoreController::config_fake_src(uint16_t link, uint16_t n_src, uint16_t data_len, uint16_t rate) {
261
262 this->sel_tx_mux(link);
263
264 auto was_en_buf = m_readout.getNode("tx_path.tx_mux.csr.ctrl.en_buf").read();
265 m_readout.getNode("tx_path.tx_mux.csr.ctrl.en_buf").write(0x0);
266 m_readout.getClient().dispatch();
267
268
269 for ( size_t src_id(0); src_id<m_core_info.srcs_per_mux; ++src_id) {
270 this->sel_tx_mux_buf(src_id);
271
272
273 bool src_en = (src_id<n_src);
274 m_readout.getNode("tx_path.tx_mux.buf.ctrl.fake_en").write(src_en);
275 m_readout.getClient().dispatch();
276 if (!src_en) {
277 continue;
278 }
279 m_readout.getNode("tx_path.tx_mux.buf.ctrl.dlen").write(data_len);
280
281 m_readout.getNode("tx_path.tx_mux.buf.ctrl.rate_rdx").write(rate);
282 m_readout.getClient().dispatch();
283 }
284
285 m_readout.getNode("tx_path.tx_mux.csr.ctrl.en_buf").write(was_en_buf.value());
286 m_readout.getClient().dispatch();
287}
288
289
290//-----------------------------------------------------------------------------
293
294 this->sel_tx_mux(link);
295
296 auto detid = m_readout.getNode("tx_path.tx_mux.mux.ctrl.detid").read();
297 auto crate = m_readout.getNode("tx_path.tx_mux.mux.ctrl.crate").read();
298 auto slot = m_readout.getNode("tx_path.tx_mux.mux.ctrl.slot").read();
299
300 m_readout.getClient().dispatch();
301
302 return {detid.value(), crate.value(), slot.value()};
303}
304
305//-----------------------------------------------------------------------------
308 this->sel_tx_mux(link);
309 this->sel_udp_core(link);
310
311 opmon::LinkInfo info;
312
313 const auto& mux_stats = m_readout.getNode("tx_path.tx_mux.csr.stat");
314 auto err = mux_stats.getNode("err").read();
315 auto eth_rdy = mux_stats.getNode("eth_rdy").read();
316 auto src_rdy = mux_stats.getNode("src_rdy").read();
317 auto udp_rdy = mux_stats.getNode("udp_rdy").read();
318 mux_stats.getClient().dispatch();
319
320 const auto& udp_ctrl = m_readout.getNode(fmt::format("tx_path.udp_core.udp_core_control"));
321 const auto& rx_stats = udp_ctrl.getNode("rx_packet_counters");
322
323 auto rx_arp_count = rx_stats.getNode("arp_count").read();
324 auto rx_ping_count = rx_stats.getNode("ping_count").read();
325 auto rx_udp_count = rx_stats.getNode("udp_count").read();
326 rx_stats.getClient().dispatch();
327
328 const auto& tx_stats = udp_ctrl.getNode("tx_packet_counters");
329
330 auto tx_arp_count = tx_stats.getNode("arp_count").read();
331 auto tx_ping_count = tx_stats.getNode("ping_count").read();
332 auto tx_udp_count = tx_stats.getNode("udp_count").read();
333 tx_stats.getClient().dispatch();
334
335
336 info.set_err(err.value());
337 info.set_eth_rdy(eth_rdy.value());
338 info.set_src_rdy(src_rdy.value());
339 info.set_udp_rdy(udp_rdy.value());
340
341 info.set_rcvd_arp_count(rx_arp_count.value());
342 info.set_rcvd_ping_count(rx_ping_count.value());
343 info.set_rcvd_udp_count(rx_udp_count.value());
344
345 info.set_sent_arp_count(tx_arp_count.value());
346 info.set_sent_ping_count(tx_ping_count.value());
347 info.set_sent_udp_count(tx_udp_count.value());
348
349 return info;
350
351 }
352
353}
354}
#define ERS_HERE
HermesCoreController(uhal::HwInterface, std::string readout_id="")
void config_udp(uint16_t link, uint64_t src_mac, uint32_t src_ip, uint16_t src_port, uint64_t dst_mac, uint32_t dst_ip, uint16_t dst_port, uint32_t filters)
void config_mux(uint16_t link, uint16_t det, uint16_t crate, uint16_t slot)
bool is_link_in_error(uint16_t link, bool do_throw=false)
void config_fake_src(uint16_t link, uint16_t n_src, uint16_t data_len, uint16_t rate)
Including Qt Headers.