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