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//-----------------------------------------------------------------------------
140void
141FIBIONode::switch_sfp_mux_channel(uint32_t mux_channel) const { // NOLINT(build/unsigned)
142 validate_sfp_id(mux_channel);
143 getNode("csr.ctrl.inmux").write(mux_channel);
144 getClient().dispatch();
145 TLOG_DEBUG(0) << "SFP input mux set to " << read_active_sfp_mux_channel();
146}
147//-----------------------------------------------------------------------------
148
149
150//-----------------------------------------------------------------------------
151uint32_t // NOLINT(build/unsigned)
153 auto active_sfp_mux_channel = getNode("csr.ctrl.inmux").read();
154 getClient().dispatch();
155 return active_sfp_mux_channel.value();
156}
157//-----------------------------------------------------------------------------
158
159
160//-----------------------------------------------------------------------------
161std::string
162FIBIONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
163 std::stringstream status;
164
165 validate_sfp_id(sfp_id);
166
167 std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
168 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
169 status << "Fanout SFP " << sfp_id << ":" << std::endl;
170 status << sfp->get_status();
171
172 if (print_out)
173 TLOG() << status.str();
174
175 return status.str();
176}
177//-----------------------------------------------------------------------------
178
179
180//-----------------------------------------------------------------------------
181void
182FIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
183 validate_sfp_id(sfp_id);
184
185 // on this board the 8 downstream sfps have their own i2c bus
186 std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
187 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
188 sfp->switch_soft_tx_control_bit(turn_on);
189}
190//-----------------------------------------------------------------------------
191
192
193//-----------------------------------------------------------------------------
194void
196 auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
197 ic_23->set_outputs(0, 0x00);
198 ic_23->set_outputs(0, 0x01);
199}
200//-----------------------------------------------------------------------------
201
202//-----------------------------------------------------------------------------
203uint8_t // NOLINT(build/unsigned)
205 auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
206
207 uint8_t sfp_los_flags = ic_23->read_inputs(0x01); // NOLINT(build/unsigned)
208 return sfp_los_flags;
209}
210//-----------------------------------------------------------------------------
211
212
213//-----------------------------------------------------------------------------
214uint8_t // NOLINT(build/unsigned)
216 auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
217
218 uint8_t sfp_fault_flags = ic_10->read_inputs(0x01); // NOLINT(build/unsigned)
219 return sfp_fault_flags;
220}
221//-----------------------------------------------------------------------------
222
223//-----------------------------------------------------------------------------
224uint8_t // NOLINT(build/unsigned)
225FIBIONode::read_sfp_los_flag(uint32_t sfp_id) const { // NOLINT(build/unsigned)
226 return read_sfp_los_flags() & (1UL << sfp_id);
227}
228//-----------------------------------------------------------------------------
229
230
231//-----------------------------------------------------------------------------
232uint8_t // NOLINT(build/unsigned)
233FIBIONode::read_sfp_fault_flag(uint32_t sfp_id) const { // NOLINT(build/unsigned)
234 return read_sfp_fault_flags() & (1UL << sfp_id);
235}
236//-----------------------------------------------------------------------------
237
238
239//-----------------------------------------------------------------------------
240void
241FIBIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
242 validate_sfp_id(sfp_id);
243
244 auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
245 uint8_t current_sfp_tx_control_flags = ic_10->read_outputs_config(0); // NOLINT(build/unsigned)
246
247 uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
248 if (turn_on)
249 {
250 new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
251 }
252 else
253 {
254 new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
255 }
256
257 ic_10->set_outputs(0, new_sfp_tx_control_flags);
258}
259//-----------------------------------------------------------------------------
260
261//-----------------------------------------------------------------------------
262bool
264{
265 std::stringstream status;
266
267 auto states = read_sub_nodes(getNode("csr.stat"));
268 bool pll_ok = states.find("pll_ok")->second.value();
269 bool mmcm_ok = states.find("mmcm_ok")->second.value();
270
271 TLOG_DEBUG(5) << "pll ok: " << pll_ok << ", mmcm ok: " << mmcm_ok;
272
273 return pll_ok && mmcm_ok;
274}
275//-----------------------------------------------------------------------------
276
277//-----------------------------------------------------------------------------
278void
279FIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
280 // on this board we have 8 downstream SFPs
281 if (sfp_id > 7) {
282 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
283 }
284}
285//-----------------------------------------------------------------------------
286
287//-----------------------------------------------------------------------------
288//void
289//FIBIONode::get_info(timinghardwareinfo::TimingFIBMonitorData& mon_data) const
290//{
291
292// auto stat_subnodes = read_sub_nodes(getNode("csr.stat"));
293// auto ctrl_subnodes = read_sub_nodes(getNode("csr.ctrl"));
294
295// mon_data.mmcm_ok = stat_subnodes.at("mmcm_ok").value();
296// mon_data.mmcm_sticky = stat_subnodes.at("mmcm_sticky").value();
297
298// mon_data.pll_ok = stat_subnodes.at("pll_ok").value();
299// mon_data.pll_sticky = stat_subnodes.at("pll_sticky").value();
300
301// mon_data.active_sfp_mux = ctrl_subnodes.at("inmux").value();
302
303// //mon_data.sfp_los_flags = read_sfp_los_flags();
304// //mon_data.sfp_fault_flags = read_sfp_fault_flags();
305// }
306//-----------------------------------------------------------------------------
307
308//-----------------------------------------------------------------------------
309// void
310// FIBIONode::get_info(opmonlib::InfoCollector& ci, int level) const
311// {
312
313// if (level >= 2) {
314// timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
315// get_pll()->get_info(pll_mon_data);
316// ci.add(pll_mon_data);
317
318// for (uint i=0; i < 8; ++i)
319// {
320// opmonlib::InfoCollector sfp_ic;
321
322// std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(i);
323// auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
324
325// try
326// {
327// sfp->get_info(sfp_ic, level);
328// }
329// catch (timing::SFPUnreachable& e)
330// {
331// // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
332// TLOG_DEBUG(2) << "Failed to communicate with SFP " << i << " on I2C switch channel " << (1UL << i) << " on i2c bus" << m_sfp_i2c_buses.at(0);
333// continue;
334// }
335// ci.add("sfp_"+std::to_string(i),sfp_ic);
336// }
337// }
338// if (level >= 1) {
339// timinghardwareinfo::TimingFIBMonitorData mon_data;
340// this->get_info(mon_data);
341// ci.add(mon_data);
342// }
343// }
344//-----------------------------------------------------------------------------
345} // namespace timing
346} // 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:287
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:210
virtual void configure_pll(const std::string &clock_config_file="") const
Configure clock chip.
Definition IONode.cpp:238
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
The DUNE-DAQ namespace.
Definition DataStore.hpp:57
void warning(const Issue &issue)
Definition ers.hpp:115