DUNE-DAQ
DUNE Trigger and Data Acquisition software
Toggle main menu visibility
Loading...
Searching...
No Matches
dunedaq
sourcecode
hermesmodules
src
HermesCoreController.cpp
Go to the documentation of this file.
1
#include "
hermesmodules/HermesCoreController.hpp
"
2
3
#include <chrono>
// std::chrono::seconds
4
#include <thread>
// std::this_thread::sleep_for
5
#include <fmt/core.h>
6
7
namespace
dunedaq
{
8
namespace
hermesmodules
{
9
10
//-----------------------------------------------------------------------------
11
HermesCoreController::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
//-----------------------------------------------------------------------------
19
HermesCoreController::~HermesCoreController
() {
20
21
}
22
23
//-----------------------------------------------------------------------------
24
void
25
HermesCoreController::load_hw_info
() {
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
59
m_core_info
.srcs_per_mux =
m_core_info
.n_src;
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
fmt::print(
"Sources per mux:{}\n"
,
m_core_info
.srcs_per_mux);
65
66
}
67
68
69
//-----------------------------------------------------------------------------
70
void
71
HermesCoreController::sel_tx_mux
(uint16_t i) {
72
if
( i >=
m_core_info
.n_mgt ) {
73
throw
LinkDoesNotExist(
ERS_HERE
, i);
74
}
75
76
m_readout
.getNode(
"tx_path.csr_tx_mux.ctrl.tx_mux_sel"
).write(i);
77
m_readout
.getClient().dispatch();
78
}
79
80
81
//-----------------------------------------------------------------------------
82
void
83
HermesCoreController::sel_tx_mux_buf
(uint16_t i) {
84
if
( i >=
m_core_info
.n_src ) {
85
throw
InputBufferDoesNotExist(
ERS_HERE
, i);
86
}
87
88
m_readout
.getNode(
"tx_path.tx_mux.csr.ctrl.sel_buf"
).write(i);
89
m_readout
.getClient().dispatch();
90
}
91
92
93
//-----------------------------------------------------------------------------
94
void
95
HermesCoreController::sel_udp_core
(uint16_t i) {
96
if
( i >=
m_core_info
.n_mgt ) {
97
throw
MgtDoesNotExist(
ERS_HERE
, i);
98
}
99
100
m_readout
.getNode(
"tx_path.csr_udp_core.ctrl.udp_core_sel"
).write(i);
101
m_readout
.getClient().dispatch();
102
}
103
104
105
//-----------------------------------------------------------------------------
106
void
107
HermesCoreController::reset
(
bool
nuke) {
108
109
if
(nuke) {
110
m_readout
.getNode(
"csr.ctrl.nuke"
).write(0x1);
111
m_readout
.getClient().dispatch();
112
113
// time.sleep(0.1);
114
std::this_thread::sleep_for (std::chrono::milliseconds(1));
115
116
m_readout
.getNode(
"csr.ctrl.nuke"
).write(0x0);
117
m_readout
.getClient().dispatch();
118
}
119
120
m_readout
.getNode(
"csr.ctrl.soft_rst"
).write(0x1);
121
m_readout
.getClient().dispatch();
122
123
// time.sleep(0.1)
124
std::this_thread::sleep_for (std::chrono::milliseconds(1));
125
126
127
m_readout
.getNode(
"csr.ctrl.soft_rst"
).write(0x0);
128
m_readout
.getClient().dispatch();
129
130
// Check the ethernet core status
131
auto
eth_rdy =
m_readout
.getNode(
"tx_path.tx_mux.csr.stat.eth_rdy"
).read();
132
m_readout
.getClient().dispatch();
133
134
// If the ethernet core is not ready, issue a phy reset
135
if
( !eth_rdy ) {
136
m_readout
.getNode(
"pcs_pma.debug.csr.ctrl.phy_reset"
).write(0x1);
137
m_readout
.getNode(
"pcs_pma.debug.csr.ctrl.phy_reset"
).write(0x0);
138
m_readout
.getClient().dispatch();
139
}
140
141
}
142
143
144
//-----------------------------------------------------------------------------
145
bool
146
HermesCoreController::is_link_in_error
(uint16_t link,
bool
do_throw) {
147
148
this->
sel_tx_mux
(link);
149
150
auto
& tx_mux_stat =
m_readout
.getNode(
"tx_path.tx_mux.csr.stat"
);
151
auto
err = tx_mux_stat.getNode(
"err"
).read();
152
auto
eth_rdy = tx_mux_stat.getNode(
"eth_rdy"
).read();
153
auto
src_rdy = tx_mux_stat.getNode(
"src_rdy"
).read();
154
auto
udp_rdy = tx_mux_stat.getNode(
"udp_rdy"
).read();
155
tx_mux_stat.getClient().dispatch();
156
157
bool
is_error = (err || !eth_rdy || !src_rdy || !udp_rdy);
158
159
if
( do_throw && is_error ) {
160
throw
LinkInError(
ERS_HERE
, link, err, eth_rdy, src_rdy, udp_rdy);
161
}
162
163
return
is_error;
164
}
165
166
//-----------------------------------------------------------------------------
167
void
168
HermesCoreController::enable
(uint16_t link,
bool
enable
) {
169
170
this->
sel_tx_mux
(link);
171
172
auto
& tx_mux_ctrl =
m_readout
.getNode(
"tx_path.tx_mux.csr.ctrl"
);
173
174
// Not sure what to do with this
175
auto
tx_en = tx_mux_ctrl.getNode(
"tx_en"
).read();
176
auto
buf_en = tx_mux_ctrl.getNode(
"en_buf"
).read();
177
auto
ctrl_en = tx_mux_ctrl.getNode(
"en"
).read();
178
179
if
(
enable
) {
180
181
// Assume that all is off
182
183
// Enable the main logic
184
tx_mux_ctrl.getNode(
"en"
).write(0x1);
185
tx_mux_ctrl.getClient().dispatch();
186
187
// Enable transmitter first
188
tx_mux_ctrl.getNode(
"tx_en"
).write(0x1);
189
tx_mux_ctrl.getClient().dispatch();
190
191
// Enable buffers last
192
tx_mux_ctrl.getNode(
"en_buf"
).write(0x1);
193
tx_mux_ctrl.getClient().dispatch();
194
195
196
}
else
{
197
198
// Disable buffers last
199
tx_mux_ctrl.getNode(
"en_buf"
).write(0x0);
200
tx_mux_ctrl.getClient().dispatch();
201
202
// Disable transmitter first
203
tx_mux_ctrl.getNode(
"tx_en"
).write(0x0);
204
tx_mux_ctrl.getClient().dispatch();
205
206
// Disable the main logic
207
tx_mux_ctrl.getNode(
"en"
).write(0x0);
208
tx_mux_ctrl.getClient().dispatch();
209
210
}
211
212
}
213
214
215
//-----------------------------------------------------------------------------
216
void
217
HermesCoreController::config_mux
(uint16_t link, uint16_t det, uint16_t crate, uint16_t slot) {
218
this->
sel_tx_mux
(link);
219
220
221
auto
& mux_ctrl =
m_readout
.getNode(
"tx_path.tx_mux.mux.ctrl"
);
222
223
mux_ctrl.getNode(
"detid"
).write(det);
224
mux_ctrl.getNode(
"crate"
).write(crate);
225
mux_ctrl.getNode(
"slot"
).write(slot);
226
mux_ctrl.getClient().dispatch();
227
228
}
229
230
231
//-----------------------------------------------------------------------------
232
void
233
HermesCoreController::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) {
234
235
if
( link >=
m_core_info
.n_mgt ) {
236
throw
LinkDoesNotExist(
ERS_HERE
, link);
237
}
238
239
this->
sel_udp_core
(link);
240
241
// const std::string udp_ctrl_name = fmt::format("udp.udp_core_{}.udp_core_control.nz_rst_ctrl");
242
const
auto
& udp_ctrl =
m_readout
.getNode(
"tx_path.udp_core.udp_core_control"
);
243
244
245
udp_ctrl.getNode(
"src_addr_ctrl.use_external"
).write(0);
246
247
// Load the source mac address
248
udp_ctrl.getNode(
"src_addr_ctrl.src_mac_addr_lower"
).write(src_mac & 0xffffffff);
249
udp_ctrl.getNode(
"src_addr_ctrl.src_mac_addr_upper"
).write((src_mac >> 32) & 0xffff);
250
251
// Load the source ip address
252
udp_ctrl.getNode(
"src_addr_ctrl.src_ip_addr"
).write(src_ip);
253
254
// Load the dst mac address
255
udp_ctrl.getNode(
"ctrl.dst_mac_addr_lower"
).write(dst_mac & 0xffffffff);
256
udp_ctrl.getNode(
"ctrl.dst_mac_addr_upper"
).write((dst_mac >> 32) & 0xffff);
257
258
// Load the dst ip address
259
udp_ctrl.getNode(
"ctrl.dst_ip_addr"
).write(dst_ip);
260
261
// Ports
262
udp_ctrl.getNode(
"src_addr_ctrl.src_port"
).write(src_port);
263
udp_ctrl.getNode(
"ctrl.dst_port"
).write(dst_port);
264
265
266
udp_ctrl.getNode(
"ctrl.filter_control"
).write(filters);
267
udp_ctrl.getClient().dispatch();
268
269
}
270
271
//-----------------------------------------------------------------------------
272
void
273
HermesCoreController::config_fake_src
(uint16_t link, uint16_t n_src, uint16_t data_len, uint16_t rate) {
274
275
this->
sel_tx_mux
(link);
276
277
auto
was_en_buf =
m_readout
.getNode(
"tx_path.tx_mux.csr.ctrl.en_buf"
).read();
278
m_readout
.getNode(
"tx_path.tx_mux.csr.ctrl.en_buf"
).write(0x0);
279
m_readout
.getClient().dispatch();
280
281
282
283
for
(
size_t
src_id(0); src_id<
m_core_info
.srcs_per_mux; ++src_id) {
284
this->
sel_tx_mux_buf
(src_id);
285
286
287
bool
src_en = (src_id<n_src);
288
m_readout
.getNode(
"tx_path.tx_mux.buf.ctrl.fake_en"
).write(src_en);
289
m_readout
.getClient().dispatch();
290
if
(!src_en) {
291
continue
;
292
}
293
m_readout
.getNode(
"tx_path.tx_mux.buf.ctrl.dlen"
).write(data_len);
294
295
m_readout
.getNode(
"tx_path.tx_mux.buf.ctrl.rate_rdx"
).write(rate);
296
m_readout
.getClient().dispatch();
297
}
298
299
m_readout
.getNode(
"tx_path.tx_mux.csr.ctrl.en_buf"
).write(was_en_buf.value());
300
m_readout
.getClient().dispatch();
301
}
302
303
304
//-----------------------------------------------------------------------------
305
HermesCoreController::LinkGeoInfo
306
HermesCoreController::read_link_geo_info
(uint16_t link) {
307
308
this->
sel_tx_mux
(link);
309
310
auto
detid
=
m_readout
.getNode(
"tx_path.tx_mux.mux.ctrl.detid"
).read();
311
auto
crate =
m_readout
.getNode(
"tx_path.tx_mux.mux.ctrl.crate"
).read();
312
auto
slot =
m_readout
.getNode(
"tx_path.tx_mux.mux.ctrl.slot"
).read();
313
314
m_readout
.getClient().dispatch();
315
316
return
{
detid
.value(), crate.value(), slot.value()};
317
}
318
319
//-----------------------------------------------------------------------------
320
opmon::LinkInfo
321
HermesCoreController::read_link_stats
(uint16_t link) {
322
this->
sel_tx_mux
(link);
323
this->
sel_udp_core
(link);
324
325
opmon::LinkInfo
info;
326
327
const
auto
& mux_stats =
m_readout
.getNode(
"tx_path.tx_mux.csr.stat"
);
328
auto
err = mux_stats.getNode(
"err"
).read();
329
auto
eth_rdy = mux_stats.getNode(
"eth_rdy"
).read();
330
auto
src_rdy = mux_stats.getNode(
"src_rdy"
).read();
331
auto
udp_rdy = mux_stats.getNode(
"udp_rdy"
).read();
332
mux_stats.getClient().dispatch();
333
334
const
auto
& udp_ctrl =
m_readout
.getNode(fmt::format(
"tx_path.udp_core.udp_core_control"
));
335
const
auto
& rx_stats = udp_ctrl.getNode(
"rx_packet_counters"
);
336
337
auto
rx_arp_count = rx_stats.getNode(
"arp_count"
).read();
338
auto
rx_ping_count = rx_stats.getNode(
"ping_count"
).read();
339
auto
rx_udp_count = rx_stats.getNode(
"udp_count"
).read();
340
rx_stats.getClient().dispatch();
341
342
const
auto
& tx_stats = udp_ctrl.getNode(
"tx_packet_counters"
);
343
344
auto
tx_arp_count = tx_stats.getNode(
"arp_count"
).read();
345
auto
tx_ping_count = tx_stats.getNode(
"ping_count"
).read();
346
auto
tx_udp_count = tx_stats.getNode(
"udp_count"
).read();
347
tx_stats.getClient().dispatch();
348
349
350
info.set_err(err.value());
351
info.set_eth_rdy(eth_rdy.value());
352
info.set_src_rdy(src_rdy.value());
353
info.set_udp_rdy(udp_rdy.value());
354
355
info.set_rcvd_arp_count(rx_arp_count.value());
356
info.set_rcvd_ping_count(rx_ping_count.value());
357
info.set_rcvd_udp_count(rx_udp_count.value());
358
359
info.set_sent_arp_count(tx_arp_count.value());
360
info.set_sent_ping_count(tx_ping_count.value());
361
info.set_sent_udp_count(tx_udp_count.value());
362
363
return
info;
364
365
}
366
367
}
368
}
HermesCoreController.hpp
ERS_HERE
#define ERS_HERE
Definition
LocalContext.hpp:141
detid
detid
Definition
TriggerActivity_serialization.hpp:47
dunedaq::hermesmodules::HermesCoreController::m_hw
uhal::HwInterface m_hw
Definition
HermesCoreController.hpp:99
dunedaq::hermesmodules::HermesCoreController::sel_udp_core
void sel_udp_core(uint16_t i)
Definition
HermesCoreController.cpp:95
dunedaq::hermesmodules::HermesCoreController::read_link_stats
opmon::LinkInfo read_link_stats(uint16_t link)
Definition
HermesCoreController.cpp:321
dunedaq::hermesmodules::HermesCoreController::m_core_info
CoreInfo m_core_info
Definition
HermesCoreController.hpp:103
dunedaq::hermesmodules::HermesCoreController::enable
void enable(uint16_t link, bool enable)
Definition
HermesCoreController.cpp:168
dunedaq::hermesmodules::HermesCoreController::HermesCoreController
HermesCoreController(uhal::HwInterface, std::string readout_id="")
Definition
HermesCoreController.cpp:11
dunedaq::hermesmodules::HermesCoreController::~HermesCoreController
virtual ~HermesCoreController()
Definition
HermesCoreController.cpp:19
dunedaq::hermesmodules::HermesCoreController::config_udp
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)
Definition
HermesCoreController.cpp:233
dunedaq::hermesmodules::HermesCoreController::config_mux
void config_mux(uint16_t link, uint16_t det, uint16_t crate, uint16_t slot)
Definition
HermesCoreController.cpp:217
dunedaq::hermesmodules::HermesCoreController::sel_tx_mux_buf
void sel_tx_mux_buf(uint16_t i)
Definition
HermesCoreController.cpp:83
dunedaq::hermesmodules::HermesCoreController::load_hw_info
void load_hw_info()
Definition
HermesCoreController.cpp:25
dunedaq::hermesmodules::HermesCoreController::reset
void reset(bool nuke=false)
Definition
HermesCoreController.cpp:107
dunedaq::hermesmodules::HermesCoreController::m_readout
const uhal::Node & m_readout
Definition
HermesCoreController.hpp:101
dunedaq::hermesmodules::HermesCoreController::is_link_in_error
bool is_link_in_error(uint16_t link, bool do_throw=false)
Definition
HermesCoreController.cpp:146
dunedaq::hermesmodules::HermesCoreController::sel_tx_mux
void sel_tx_mux(uint16_t i)
Definition
HermesCoreController.cpp:71
dunedaq::hermesmodules::HermesCoreController::read_link_geo_info
LinkGeoInfo read_link_geo_info(uint16_t link)
Definition
HermesCoreController.cpp:306
dunedaq::hermesmodules::HermesCoreController::config_fake_src
void config_fake_src(uint16_t link, uint16_t n_src, uint16_t data_len, uint16_t rate)
Definition
HermesCoreController.cpp:273
dunedaq::hermesmodules::opmon::LinkInfo
Definition
hermescontroller.pb.h:83
dunedaq::hermesmodules
Definition
HermesCoreController.hpp:44
dunedaq
Including Qt Headers.
Definition
module.cpp:16
enable
Definition
enable.py:1
dunedaq::hermesmodules::HermesCoreController::LinkGeoInfo
Definition
HermesCoreController.hpp:61
Generated on
for DUNE-DAQ by
1.17.0