Line data Source code
1 : /**
2 : * @file MasterGlobalNode.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/MasterGlobalNode.hpp"
10 :
11 : #include "logging/Logging.hpp"
12 :
13 : #include <string>
14 :
15 : namespace dunedaq {
16 : namespace timing {
17 :
18 0 : UHAL_REGISTER_DERIVED_NODE(MasterGlobalNode)
19 :
20 : //-----------------------------------------------------------------------------
21 0 : MasterGlobalNode::MasterGlobalNode(const uhal::Node& node)
22 0 : : TimingNode(node)
23 0 : {}
24 : //-----------------------------------------------------------------------------
25 :
26 : //-----------------------------------------------------------------------------
27 0 : MasterGlobalNode::~MasterGlobalNode() {}
28 : //-----------------------------------------------------------------------------
29 :
30 : //-----------------------------------------------------------------------------
31 : std::string
32 0 : MasterGlobalNode::get_status(bool print_out) const
33 : {
34 0 : std::stringstream status;
35 0 : auto ctrl = read_sub_nodes(getNode("csr.ctrl"));
36 0 : status << format_reg_table(ctrl, "Master global controls");
37 :
38 0 : auto stat = read_sub_nodes(getNode("csr.stat"));
39 0 : status << format_reg_table(stat, "Master global state");
40 0 : if (print_out)
41 0 : TLOG() << status.str();
42 0 : return status.str();
43 0 : }
44 : //-----------------------------------------------------------------------------
45 :
46 : //-----------------------------------------------------------------------------
47 : void
48 0 : MasterGlobalNode::enable_upstream_endpoint(uint32_t timeout) const // NOLINT(build/unsigned)
49 : {
50 0 : getNode("csr.ctrl.resync_cdr").write(0x1);
51 0 : getNode("csr.ctrl.resync").write(0x1);
52 0 : getClient().dispatch();
53 :
54 0 : getNode("csr.ctrl.resync_cdr").write(0x0);
55 0 : getNode("csr.ctrl.resync").write(0x0);
56 0 : getClient().dispatch();
57 :
58 0 : TLOG_DEBUG(4) << "Upstream CDR reset, waiting for lock";
59 :
60 0 : auto start = std::chrono::high_resolution_clock::now();
61 :
62 : // Wait for the rx and cdr to be happy
63 0 : while (true) {
64 0 : auto rx_ready = getNode("csr.stat.rx_rdy").read();
65 0 : auto cdr_ready = getNode("csr.stat.cdr_locked").read();
66 0 : getClient().dispatch();
67 :
68 0 : TLOG_DEBUG(6) << std::hex << "rx ready: 0x" << rx_ready.value() << ", cdr ready: " << cdr_ready.value();
69 :
70 0 : if (rx_ready.value() && cdr_ready.value())
71 : {
72 0 : TLOG_DEBUG(4) << "Master CDR and rx block ready!";
73 0 : break;
74 : }
75 :
76 0 : auto now = std::chrono::high_resolution_clock::now();
77 0 : auto ms_since_start = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
78 :
79 0 : if (ms_since_start.count() > timeout)
80 0 : throw ReceiverNotReady(ERS_HERE, cdr_ready.value(), rx_ready.value());
81 :
82 0 : std::this_thread::sleep_for(std::chrono::microseconds(10));
83 0 : }
84 0 : }
85 : //-----------------------------------------------------------------------------
86 :
87 : //-----------------------------------------------------------------------------
88 : bool
89 0 : MasterGlobalNode::read_upstream_endpoint_ready() const
90 : {
91 0 : auto rx_ready = getNode("csr.stat.rx_rdy").read();
92 0 : getClient().dispatch();
93 0 : return rx_ready.value();
94 0 : }
95 : //-----------------------------------------------------------------------------
96 :
97 : //-----------------------------------------------------------------------------
98 : void
99 0 : MasterGlobalNode::reset_command_counters(uint32_t timeout) const // NOLINT(build/unsigned)
100 : {
101 0 : getNode("csr.ctrl.clr_ctrs").write(0x1);
102 0 : getClient().dispatch();
103 :
104 0 : TLOG_DEBUG(1) << "Command counters reset, waiting for them to be ready";
105 :
106 0 : auto start = std::chrono::high_resolution_clock::now();
107 :
108 0 : std::chrono::milliseconds ms_since_start(0);
109 :
110 0 : uhal::ValWord<uint32_t> counters_ready; // NOLINT(build/unsigned)
111 :
112 : // Wait for the endpoint to be happy
113 0 : while (ms_since_start.count() < timeout) {
114 0 : auto now = std::chrono::high_resolution_clock::now();
115 0 : ms_since_start = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
116 :
117 0 : millisleep(10);
118 :
119 0 : counters_ready = getNode("csr.stat.ctrs_rdy").read();
120 0 : getClient().dispatch();
121 :
122 0 : TLOG_DEBUG(6) << "counters ready: 0x" << counters_ready.value();
123 :
124 0 : if (counters_ready.value()) {
125 0 : TLOG_DEBUG(4) << "Master command counters ready!";
126 0 : return;
127 : }
128 : }
129 :
130 0 : if (!counters_ready.value()) {
131 : // TODO throw something
132 0 : TLOG() << "Command counters did not become ready";
133 : } else {
134 0 : TLOG_DEBUG(4) << "Command counters ready";
135 : }
136 0 : }
137 : //-----------------------------------------------------------------------------
138 :
139 : //-----------------------------------------------------------------------------
140 : bool
141 0 : MasterGlobalNode::read_counters_ready() const
142 : {
143 0 : auto counters_ready = getNode("csr.stat.ctrs_rdy").read();
144 0 : getClient().dispatch();
145 0 : return counters_ready.value();
146 0 : }
147 : //-----------------------------------------------------------------------------
148 :
149 : } // namespace timing
150 : } // namespace dunedaq
|