DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
FIBIONode.cpp
Go to the documentation of this file.
1
10
11#include <map>
12#include <string>
13#include <utility>
14#include <vector>
15
16namespace dunedaq {
17namespace timing {
18
19UHAL_REGISTER_DERIVED_NODE(FIBIONode)
20
21//-----------------------------------------------------------------------------
22FIBIONode::FIBIONode(const uhal::Node& aNode) :
23 SFPMuxIONode(aNode, "i2c", "i2c", "SI5345", {"PLL", "BKP DATA"}, {"i2c_sfp0", "i2c_sfp1", "i2c_sfp2", "i2c_sfp3", "i2c_sfp4", "i2c_sfp5", "i2c_sfp6", "i2c_sfp7"}) {
24}
25//-----------------------------------------------------------------------------
26
27
28//-----------------------------------------------------------------------------
31//-----------------------------------------------------------------------------
32
33//-----------------------------------------------------------------------------
34std::string
36{
37 return "UID_PROM";
38}
39//-----------------------------------------------------------------------------
40
41//-----------------------------------------------------------------------------
42std::string
43FIBIONode::get_status(bool print_out) const {
44 std::stringstream status;
45 auto subnodes = read_sub_nodes(getNode("csr.stat"));
46
47 uint32_t sfp_los_flags = read_sfp_los_flags(); // NOLINT(build/unsigned)
48 uint32_t sfp_fault_flags = read_sfp_fault_flags(); // NOLINT(build/unsigned)
49
50 std::vector<std::pair<std::string, std::string>> sfps_summary;
51 sfps_summary.push_back(std::make_pair("SFP LOS flags", format_reg_value(sfp_los_flags, 16)));
52 sfps_summary.push_back(std::make_pair("SFP fault flags", format_reg_value(sfp_fault_flags, 16)));
53
54 status << format_reg_table(subnodes, "FIB IO state") << std::endl;
55 status << format_reg_table(sfps_summary, "FIB SFPs state");
56
57 if (print_out)
58 TLOG() << status.str();
59
60 return status.str();
61}
62//-----------------------------------------------------------------------------
63
64
65//-----------------------------------------------------------------------------
66void
67FIBIONode::reset(const std::string& clock_config_file) const {
68
69 // Soft reset
71
72 millisleep(1000);
73
74 // Reset I2C
75 getNode("csr.ctrl.rstb_i2c").write(0x1);
76 getNode("csr.ctrl.rstb_i2c").write(0x0);
77
78 getNode("csr.ctrl.rst").write(0x1);
79 getNode("csr.ctrl.rst").write(0x0);
80
81 getClient().dispatch();
82
84
85 if (carrier_type == kCarrierEnclustraA35) {
86 // enclustra i2c switch stuff
87 try {
88 getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
89 } catch (const std::exception& e) {
90 ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
91 }
92 }
93
94 // Configure I2C IO expanders
95 auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
96 auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
97
98 // Bank 0
99 ic_10->set_inversion(0, 0x00);
100
101 // all out, sfp tx disable
102 ic_10->set_io(0, 0x00);
103 // sfp laser on by default
104 ic_10->set_outputs(0, 0x00);
105
106 // Bank 1
107 ic_10->set_inversion(1, 0x00);
108 // all inputs, sfp fault
109 ic_10->set_io(1, 0xff);
110
111 // Bank 0
112 ic_23->set_inversion(0, 0x00);
113 // pin 0 - out: pll rst, pins 1-4 pll and cdr flags
114 ic_23->set_io(0, 0xfe);
115 ic_23->set_outputs(0, 0x01);
116
117 // Bank 1
118 ic_23->set_inversion(1, 0x00);
119 // all inputs, sfp los
120 ic_23->set_io(1, 0xff);
121
122 // reset pll via I2C IO expanders
123 reset_pll();
124
125 // Upload config file to PLL
126 configure_pll(clock_config_file);
127
128 //getNode("csr.ctrl.inmux").write(0);
129 //getClient().dispatch();
130
131// To be removed from firmware address maps also
132// getNode("csr.ctrl.rst_lock_mon").write(0x1);
133// getNode("csr.ctrl.rst_lock_mon").write(0x0);
134// getClient().dispatch();
135
136 TLOG() << "Reset done";
137}
138//-----------------------------------------------------------------------------
139
140//-----------------------------------------------------------------------------
141void
142FIBIONode::switch_sfp_mux_channel(uint32_t mux_channel) const { // NOLINT(build/unsigned)
143 validate_sfp_id(mux_channel);
144 getNode("csr.ctrl.inmux").write(mux_channel);
145 getClient().dispatch();
146 TLOG_DEBUG(0) << "SFP input mux set to " << read_active_sfp_mux_channel();
147}
148//-----------------------------------------------------------------------------
149
150
151//-----------------------------------------------------------------------------
152uint32_t // NOLINT(build/unsigned)
154 auto active_sfp_mux_channel = getNode("csr.ctrl.inmux").read();
155 getClient().dispatch();
156 return active_sfp_mux_channel.value();
157}
158//-----------------------------------------------------------------------------
159
160
161//-----------------------------------------------------------------------------
162std::string
163FIBIONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
164 std::stringstream status;
165
166 validate_sfp_id(sfp_id);
167
168 std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
169 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
170 status << "Fanout SFP " << sfp_id << ":" << std::endl;
171 status << sfp->get_status();
172
173 if (print_out)
174 TLOG() << status.str();
175
176 return status.str();
177}
178//-----------------------------------------------------------------------------
179
180
181//-----------------------------------------------------------------------------
182void
183FIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
184 validate_sfp_id(sfp_id);
185
186 // on this board the 8 downstream sfps have their own i2c bus
187 std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
188 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
189 sfp->switch_soft_tx_control_bit(turn_on);
190}
191//-----------------------------------------------------------------------------
192
193
194//-----------------------------------------------------------------------------
195void
197 auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
198 ic_23->set_outputs(0, 0x00);
199 ic_23->set_outputs(0, 0x01);
200}
201//-----------------------------------------------------------------------------
202
203//-----------------------------------------------------------------------------
204uint8_t // NOLINT(build/unsigned)
206 auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
207
208 uint8_t sfp_los_flags = ic_23->read_inputs(0x01); // NOLINT(build/unsigned)
209 return sfp_los_flags;
210}
211//-----------------------------------------------------------------------------
212
213
214//-----------------------------------------------------------------------------
215uint8_t // NOLINT(build/unsigned)
217 auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
218
219 uint8_t sfp_fault_flags = ic_10->read_inputs(0x01); // NOLINT(build/unsigned)
220 return sfp_fault_flags;
221}
222//-----------------------------------------------------------------------------
223
224//-----------------------------------------------------------------------------
225uint8_t // NOLINT(build/unsigned)
226FIBIONode::read_sfp_los_flag(uint32_t sfp_id) const { // NOLINT(build/unsigned)
227 return read_sfp_los_flags() & (1UL << sfp_id);
228}
229//-----------------------------------------------------------------------------
230
231
232//-----------------------------------------------------------------------------
233uint8_t // NOLINT(build/unsigned)
234FIBIONode::read_sfp_fault_flag(uint32_t sfp_id) const { // NOLINT(build/unsigned)
235 return read_sfp_fault_flags() & (1UL << sfp_id);
236}
237//-----------------------------------------------------------------------------
238
239
240//-----------------------------------------------------------------------------
241void
242FIBIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
243 validate_sfp_id(sfp_id);
244
245 auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
246 uint8_t current_sfp_tx_control_flags = ic_10->read_outputs_config(0); // NOLINT(build/unsigned)
247
248 uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
249 if (turn_on)
250 {
251 new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
252 }
253 else
254 {
255 new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
256 }
257
258 ic_10->set_outputs(0, new_sfp_tx_control_flags);
259}
260//-----------------------------------------------------------------------------
261
262//-----------------------------------------------------------------------------
263bool
265{
266 std::stringstream status;
267
268 auto states = read_sub_nodes(getNode("csr.stat"));
269 bool pll_ok = states.find("pll_ok")->second.value();
270 bool mmcm_ok = states.find("mmcm_ok")->second.value();
271
272 TLOG_DEBUG(5) << "pll ok: " << pll_ok << ", mmcm ok: " << mmcm_ok;
273
274 return pll_ok && mmcm_ok;
275}
276//-----------------------------------------------------------------------------
277
278//-----------------------------------------------------------------------------
279void
280FIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
281 // on this board we have 8 downstream SFPs
282 if (sfp_id > 7) {
283 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
284 }
285}
286//-----------------------------------------------------------------------------
287
288//-----------------------------------------------------------------------------
289//void
290//FIBIONode::get_info(timinghardwareinfo::TimingFIBMonitorData& mon_data) const
291//{
292
293// auto stat_subnodes = read_sub_nodes(getNode("csr.stat"));
294// auto ctrl_subnodes = read_sub_nodes(getNode("csr.ctrl"));
295
296// mon_data.mmcm_ok = stat_subnodes.at("mmcm_ok").value();
297// mon_data.mmcm_sticky = stat_subnodes.at("mmcm_sticky").value();
298
299// mon_data.pll_ok = stat_subnodes.at("pll_ok").value();
300// mon_data.pll_sticky = stat_subnodes.at("pll_sticky").value();
301
302// mon_data.active_sfp_mux = ctrl_subnodes.at("inmux").value();
303
304// //mon_data.sfp_los_flags = read_sfp_los_flags();
305// //mon_data.sfp_fault_flags = read_sfp_fault_flags();
306// }
307//-----------------------------------------------------------------------------
308
309//-----------------------------------------------------------------------------
310// void
311// FIBIONode::get_info(opmonlib::InfoCollector& ci, int level) const
312// {
313
314// if (level >= 2) {
315// timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
316// get_pll()->get_info(pll_mon_data);
317// ci.add(pll_mon_data);
318
319// for (uint i=0; i < 8; ++i)
320// {
321// opmonlib::InfoCollector sfp_ic;
322
323// std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(i);
324// auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
325
326// try
327// {
328// sfp->get_info(sfp_ic, level);
329// }
330// catch (timing::SFPUnreachable& e)
331// {
332// // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
333// TLOG_DEBUG(2) << "Failed to communicate with SFP " << i << " on I2C switch channel " << (1UL << i) << " on i2c bus" << m_sfp_i2c_buses.at(0);
334// continue;
335// }
336// ci.add("sfp_"+std::to_string(i),sfp_ic);
337// }
338// }
339// if (level >= 1) {
340// timinghardwareinfo::TimingFIBMonitorData mon_data;
341// this->get_info(mon_data);
342// ci.add(mon_data);
343// }
344// }
345//-----------------------------------------------------------------------------
346} // namespace timing
347} // namespace dunedaq
#define ERS_HERE
Class for the FIB board.
Definition FIBIONode.hpp:32
uint8_t read_sfp_fault_flag(uint32_t sfp_id) const
reset on-board SFP flags using I2C IO expanders
void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const override
control tx laser of on-board SFP softly (I2C command)
void validate_sfp_id(uint32_t sfp_id) const
Fill hardware monitoring structure.
uint8_t read_sfp_los_flags() const
reset on-board SFP flags using I2C IO expanders
uint8_t read_sfp_fault_flags() const
reset on-board SFP flags using I2C IO expanders
void reset(const std::string &clock_config_file) const override
Reset FIB node.
Definition FIBIONode.cpp:67
std::string get_sfp_status(uint32_t sfp_id, bool print_out=false) const override
Print status of on-board SFP.
void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override
reset on-board SFP flags using I2C IO expanders
uint32_t read_active_sfp_mux_channel() const override
Read the active SFP mux channel.
void reset_pll() const
reset on-board PLL using I2C IO expanders
void switch_sfp_mux_channel(uint32_t mux_channel) const override
Switch the SFP mux channel.
uint8_t read_sfp_los_flag(uint32_t sfp_id) const
reset on-board SFP flags using I2C IO expanders
std::string get_uid_address_parameter_name() const override
Get the UID address parameter name.
Definition FIBIONode.cpp:35
bool clocks_ok() const override
Clocks ready?
std::string get_status(bool print_out=false) const override
Get status string, optionally print.
Definition FIBIONode.cpp:43
virtual void write_soft_reset_register() const
Write soft reset register.
Definition IONode.cpp:296
virtual uint32_t read_carrier_type() const
Read the word identifying the FPFA carrier board.
Definition IONode.cpp:58
const std::string m_uid_i2c_bus
Definition IONode.hpp:200
virtual void configure_pll(const std::string &clock_config_file="") const
Configure clock chip.
Definition IONode.cpp:247
std::unique_ptr< const T > get_i2c_device(const std::string &i2c_bus_name, const std::string &i2c_device_name) const
Get the an I2C chip.
Definition IONode.hxx:6
Base class for boards which have a physical SFP mux.
std::map< std::string, uhal::ValWord< uint32_t > > read_sub_nodes(const uhal::Node &node, bool dispatch=true) const
Read subnodes.
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
#define TLOG(...)
Definition macro.hpp:22
CarrierType convert_value_to_carrier_type(uint32_t darrier_type)
Definition toolbox.cpp:287
std::string format_reg_table(T data, std::string title, std::vector< std::string > headers)
Format reg-value table.
Definition toolbox.hxx:166
std::string format_reg_value(T reg_value, uint32_t base)
Definition toolbox.hxx:117
void millisleep(const double &time_in_milliseconds)
Definition toolbox.cpp:83
Including Qt Headers.
void warning(const Issue &issue)
Definition ers.hpp:115