DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
MIBIONode.cpp
Go to the documentation of this file.
1
10
11#include <string>
12#include <math.h>
13
14namespace dunedaq {
15namespace timing {
16
17UHAL_REGISTER_DERIVED_NODE(MIBIONode)
18
19//-----------------------------------------------------------------------------
20MIBIONode::MIBIONode(const uhal::Node& node)
21 : IONode(node, "i2c", "i2c", { "PLL" }, { "PLL", "CDR 0", "CDR 1" }, { "i2c" })
22{
23}
24//-----------------------------------------------------------------------------
25
26//-----------------------------------------------------------------------------
28//-----------------------------------------------------------------------------
29
30//-----------------------------------------------------------------------------
31std::string
33{
34 return "UID_PROM";
35}
36//-----------------------------------------------------------------------------
37
38//-----------------------------------------------------------------------------
39std::string
40MIBIONode::get_status(bool print_out) const
41{
42 std::stringstream status;
43
44 auto subnodes = read_sub_nodes(getNode("csr.stat"));
45 status << format_reg_table(subnodes, "MIB IO state");
46
47 if (print_out)
48 TLOG() << std::endl << status.str();
49 return status.str();
50}
51//-----------------------------------------------------------------------------
52
53//-----------------------------------------------------------------------------
54void
55MIBIONode::configure_pll(const std::string& clock_config_file) const
56{
57 // enable pll channel (#3) only
58 auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
59 i2c_switch->set_channels_states(8);
60 IONode::configure_pll(clock_config_file);
61}
62//-----------------------------------------------------------------------------
63
64//-----------------------------------------------------------------------------
65std::string
66MIBIONode::get_pll_status(bool print_out) const
67{
68 // enable pll channel (#3) only
69 auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
70 i2c_switch->set_channels_states(8);
71 return IONode::get_pll_status(print_out);
72}
73//-----------------------------------------------------------------------------
74
75//-----------------------------------------------------------------------------
76void
77MIBIONode::reset(const std::string& clock_config_file) const
78{
80
81 millisleep(1000);
82
83 // Upload config file to PLL
84 configure_pll(clock_config_file);
85
86 // Reset mmcm
87 getNode("csr.ctrl.rst").write(0x1);
88 getNode("csr.ctrl.rst").write(0x0);
89
90 getNode("io_select.csr.ctrl.amc_out").write(0xfff);
91 getNode("io_select.csr.ctrl.amc_in").write(0x0);
92 getNode("io_select.csr.ctrl.usfp_src").write(0x0);
93
94 getClient().dispatch();
95
96 TLOG() << "Reset done";
97}
98//-----------------------------------------------------------------------------
99
100//-----------------------------------------------------------------------------
101bool
103{
104 TLOG() << "clock check needs to be implemented";
105 return false;
106}
107//-----------------------------------------------------------------------------
108
109//-----------------------------------------------------------------------------
110//void
111//MIBIONode::switch_downstream_mux_channel(uint32_t mux_channel) const // NOLINT(build/unsigned)
112//{
113// validate_amc_slot(mux_channel);
114// uint16_t amc_in_bit = 0x1 << (mux_channel-1);
115// getNode("io_select.csr.ctrl.amc_in").write(amc_in_bit);
116//
117// TLOG_DEBUG(3) << " MIB downstream AMC (in) " << mux_channel << " enabled";
118// getClient().dispatch();
119//}
120//-----------------------------------------------------------------------------
121
122//-----------------------------------------------------------------------------
123//uint32_t // NOLINT(build/unsigned)
124//MIBIONode::read_active_downstream_mux_channel() const
125//{
126// auto active_mux_channel_bits = getNode("io_select.csr.ctrl.amc_in").read();
127// getClient().dispatch();
128// double mux = log2(active_mux_channel_bits.value());
129// return mux+1;
130//}
131//-----------------------------------------------------------------------------
132
133//-----------------------------------------------------------------------------
134//void
135//MIBIONode::switch_upstream_mux_channel(uint32_t mux_channel) const // NOLINT(build/unsigned)
136//{
137// getNode("io_select.csr.ctrl.usfp_src").write(mux_channel);
138// TLOG_DEBUG(3) << " MIB upstream SFP (in) " << mux_channel << " enabled";
139// // TODO what about clock config?
140// getClient().dispatch();
141//}
142//-----------------------------------------------------------------------------
143
144//-----------------------------------------------------------------------------
145//uint32_t // NOLINT(build/unsigned)
146//MIBIONode::read_active_upstream_mux_channel() const
147//{
148// auto active_sfp_mux_channel = getNode("io_select.csr.ctrl.usfp_src").read();
149// getClient().dispatch();
150// return active_sfp_mux_channel.value();
151//}
152//-----------------------------------------------------------------------------
153
154//-----------------------------------------------------------------------------
155std::string
156MIBIONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
157 std::stringstream status;
158
159 validate_sfp_id(sfp_id);
160
161 // enable i2c path for sfp
162 auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
163 i2c_switch->set_channels_states(1UL << sfp_id);
164
165 auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
166
167 status << "SFP " << sfp_id << ":" << std::endl;
168
169 try
170 {
171 status << sfp->get_status();
172 }
173 catch(...)
174 {
175 i2c_switch->set_channels_states(8);
176 throw;
177 }
178
179 i2c_switch->set_channels_states(8);
180
181 if (print_out)
182 TLOG() << status.str();
183
184 return status.str();
185}
186//-----------------------------------------------------------------------------
187
188//-----------------------------------------------------------------------------
189void
190MIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
191 validate_sfp_id(sfp_id);
192
193 auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
194 i2c_switch->set_channels_states(1UL << sfp_id);
195 auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
196 sfp->switch_soft_tx_control_bit(turn_on);
197 i2c_switch->set_channels_states(8);
198}
199//-----------------------------------------------------------------------------
200
201//-----------------------------------------------------------------------------
202// void
203// MIBIONode::get_info(timinghardwareinfo::TimingMIBMonitorData& mon_data) const
204// {
205
206// auto subnodes = read_sub_nodes(getNode("csr.stat"));
207
208// mon_data.cdr_0_lol = subnodes.at("cdr_lol").value() & 0x1;
209// mon_data.cdr_1_lol = subnodes.at("cdr_lol").value() & 0x2;
210
211// mon_data.cdr_0_los = subnodes.at("cdr_los").value() & 0x1;
212// mon_data.cdr_1_los = subnodes.at("cdr_los").value() & 0x2;
213
214// mon_data.mmcm_ok = subnodes.at("mmcm_ok").value();
215// mon_data.mmcm_sticky = subnodes.at("mmcm_sticky").value();
216
217// mon_data.sfp_0_flt = subnodes.at("sfp_flt").value() & 0x1;
218// mon_data.sfp_1_flt = subnodes.at("sfp_flt").value() & 0x2;
219
220// mon_data.sfp_0_los = subnodes.at("sfp_los").value() & 0x1;
221// mon_data.sfp_1_los = subnodes.at("sfp_los").value() & 0x2;
222
223// // TODO 3rd SFP?
224// }
225// //-----------------------------------------------------------------------------
226
227// //-----------------------------------------------------------------------------
228// void
229// MIBIONode::get_info(opmonlib::InfoCollector& ci, int level) const
230// {
231// auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
232
233// if (level >= 2) {
234// i2c_switch->set_channels_states(8);
235
236// timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
237// get_pll()->get_info(pll_mon_data);
238// ci.add(pll_mon_data);
239
240// for (uint i=0; i < 3; ++i)
241// {
242// opmonlib::InfoCollector sfp_ic;
243
244// // enable i2c path for sfp
245// i2c_switch->set_channels_states(1UL << i);
246
247// auto sfp = this->get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
248
249// try
250// {
251// sfp->get_info(sfp_ic, level);
252// }
253// catch (timing::SFPUnreachable& e)
254// {
255// // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
256// TLOG_DEBUG(2) << "Failed to communicate with SFP " << i << " on I2C switch channel " << (1UL << i) << " on i2c bus" << m_sfp_i2c_buses.at(0);
257// continue;
258// }
259// ci.add("sfp_"+std::to_string(i),sfp_ic);
260// }
261// i2c_switch->set_channels_states(8);
262// }
263// if (level >= 1) {
264// timinghardwareinfo::TimingMIBMonitorData mon_data;
265// this->get_info(mon_data);
266// ci.add(mon_data);
267// }
268// }
269//-----------------------------------------------------------------------------
270
271//-----------------------------------------------------------------------------
272void
273MIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
274 // on this board we have 3 upstream SFPs
275 if (sfp_id > 2) {
276 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
277 }
278}
279//-----------------------------------------------------------------------------
280
281//-----------------------------------------------------------------------------
282void
283MIBIONode::validate_amc_slot(uint32_t amc_slot) const { // NOLINT(build/unsigned)
284 if (amc_slot < 1 || amc_slot > 12) {
285 throw InvalidAMCSlot(ERS_HERE, format_reg_value(amc_slot, 10));
286 }
287}
288//-----------------------------------------------------------------------------
289} // namespace timing
290} // namespace dunedaq
#define ERS_HERE
Base class for timing IO nodes.
Definition IONode.hpp:44
virtual void write_soft_reset_register() const
Write soft reset register.
Definition IONode.cpp:296
const std::vector< std::string > m_sfp_i2c_buses
Definition IONode.hpp:204
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
virtual std::string get_pll_status(bool print_out=false) const
Print status of on-board PLL.
Definition IONode.cpp:288
Class for the timing FMC board.
Definition MIBIONode.hpp:34
void validate_sfp_id(uint32_t sfp_id) const
Fill hardware monitoring structure.
std::string get_uid_address_parameter_name() const override
Get the UID address parameter name.
Definition MIBIONode.cpp:32
void validate_amc_slot(uint32_t amc_slot) const
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)
std::string get_sfp_status(uint32_t sfp_id, bool print_out=false) const override
Switch the SFP mux channel.
void reset(const std::string &clock_config_file) const override
Reset MIB IO.
Definition MIBIONode.cpp:77
std::string get_status(bool print_out=false) const override
Get status string, optionally print.
Definition MIBIONode.cpp:40
bool clocks_ok() const override
Clocks ready?
void configure_pll(const std::string &clock_config_file="") const override
Configure clock chip.
Definition MIBIONode.cpp:55
std::string get_pll_status(bool print_out=false) const override
Print status of on-board PLL.
Definition MIBIONode.cpp:66
std::map< std::string, uhal::ValWord< uint32_t > > read_sub_nodes(const uhal::Node &node, bool dispatch=true) const
Read subnodes.
#define TLOG(...)
Definition macro.hpp:22
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.