DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
FIBV2IONode.cpp
Go to the documentation of this file.
1
10#include "timing/LM75Node.hpp"
11
12#include <map>
13#include <string>
14#include <utility>
15#include <vector>
16
17namespace dunedaq {
18namespace timing {
19
20UHAL_REGISTER_DERIVED_NODE(FIBV2IONode)
21
22//-----------------------------------------------------------------------------
23FIBV2IONode::FIBV2IONode(const uhal::Node& aNode) :
24 IONode(aNode, "i2c", "i2c", "SI5345", {"PLL", "BKP DATA"}, {"i2c_sfp0", "i2c_sfp1", "i2c_sfp2", "i2c_sfp3", "i2c_sfp4", "i2c_sfp5", "i2c_sfp6", "i2c_sfp7"}) {
25}
26//-----------------------------------------------------------------------------
27
28
29//-----------------------------------------------------------------------------
32//-----------------------------------------------------------------------------
33
34//-----------------------------------------------------------------------------
35std::string
37{
38 return "UID_PROM";
39}
40//-----------------------------------------------------------------------------
41
42//-----------------------------------------------------------------------------
43void
44FIBV2IONode::configure_pll(const std::string& /*clock_config_file*/) const
45{
46 TLOG() << "No text config for CDCLVD110";
47}
48//-----------------------------------------------------------------------------
49
50//-----------------------------------------------------------------------------
51std::string
52FIBV2IONode::get_status(bool print_out) const
53{
54 std::stringstream status;
55 auto subnodes = read_sub_nodes(getNode("csr.stat"));
56 status << format_reg_table(subnodes, "FIB IO state") << std::endl;
57
58 status << "Board temperature: " << read_board_temperature() << " [C]" << std::endl;
59
60 if (print_out)
61 TLOG() << status.str();
62
63 return status.str();
64}
65//-----------------------------------------------------------------------------
66
67//-----------------------------------------------------------------------------
68void
69FIBV2IONode::reset(const ClockSource& clock_source) const {
70
71 // Soft reset
73
74 millisleep(1000);
75
76 getNode("csr.ctrl.rst").write(0x1);
77 getNode("csr.ctrl.rst").write(0x0);
78
79 getClient().dispatch();
80
81 getNode("csr.ctrl.clk_enable").write(0x0);
82
83 if (clock_source == kInput0)
84 {
85 getNode("csr.ctrl.clk_select").write(0x0);
86 }
87 else if (clock_source == kInput1)
88 {
89 getNode("csr.ctrl.clk_select").write(0x1);
90 }
91 else
92 {
93 // TODO :throw something here
94 }
95
96 getClient().dispatch();
97
98 TLOG() << "Reset done";
99}
100//-----------------------------------------------------------------------------
101
102//-----------------------------------------------------------------------------
104{
105}
106//-----------------------------------------------------------------------------
107
108
109//-----------------------------------------------------------------------------
110std::string
111FIBV2IONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
112 std::stringstream status;
113
114 validate_sfp_id(sfp_id);
115
116 std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
117 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
118 status << "FIB V2 SFP " << sfp_id << ":" << std::endl;
119 status << sfp->get_status();
120
121 if (print_out)
122 TLOG() << status.str();
123
124 return status.str();
125}
126//-----------------------------------------------------------------------------
127
128//-----------------------------------------------------------------------------
129void
130FIBV2IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
131 validate_sfp_id(sfp_id);
132
133 // on this board the 8 downstream sfps have their own i2c bus
134 std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
135 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
136 sfp->switch_soft_tx_control_bit(turn_on);
137}
138//-----------------------------------------------------------------------------
139
140//-----------------------------------------------------------------------------
141void
142FIBV2IONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
143
144 validate_sfp_id(sfp_id);
145
146 auto sfp_tx_control_flags = getNode("csr.ctrl.sfp_tx_disable").read(); // NOLINT(build/unsigned)
147 getClient().dispatch();
148
149 uint8_t current_sfp_tx_control_flags=sfp_tx_control_flags.value();
150 uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
151
152 if (turn_on)
153 {
154 new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
155 }
156 else
157 {
158 new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
159 }
160
161 getNode("csr.ctrl.sfp_tx_disable").write(new_sfp_tx_control_flags);
162 getClient().dispatch();
163}
164//-----------------------------------------------------------------------------
165
166//-----------------------------------------------------------------------------
167void
169{
170 mon_data.lol = false; // no monitoring of this in CDCLVD110
171 mon_data.los = false;
172}
173//-----------------------------------------------------------------------------
174
175//-----------------------------------------------------------------------------
176std::string
177FIBV2IONode::get_pll_status(bool print_out) const
178{
179 std::stringstream status;
180 status << "No status yet for CDCLVD110 on FIBv2";
181
182 if (print_out)
183 TLOG() << status.str();
184
185 return status.str();
186}
187//-----------------------------------------------------------------------------
188
189//-----------------------------------------------------------------------------
190float
192{
193 auto temp_mon = get_i2c_device<LM75Node>(m_pll_i2c_bus, "TEMP_MON");
194 return temp_mon->read_temperature();
195}
196//-----------------------------------------------------------------------------
197
198//-----------------------------------------------------------------------------
199//std::unique_ptr<const CDCLVD110Node>
200//FIBV2IONode::get_pll() const
201//{
202// return &getNode<CDCLVD110Node>("clock_gen"); //TODO: future node
203//}
204//-----------------------------------------------------------------------------
205
206//-----------------------------------------------------------------------------
207void
208FIBV2IONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
209 // on this board we have 8 downstream SFPs
210 if (sfp_id > 7) {
211 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
212 }
213}
214//-----------------------------------------------------------------------------
215
216//-----------------------------------------------------------------------------
217//void
218//FIBV2IONode::get_info(timinghardwareinfo::TimingFIBMonitorData& mon_data) const
219//{
220
221// auto stat_subnodes = read_sub_nodes(getNode("csr.stat"));
222// auto ctrl_subnodes = read_sub_nodes(getNode("csr.ctrl"));
223
224// mon_data.mmcm_ok = stat_subnodes.at("mmcm_ok").value();
225// mon_data.mmcm_sticky = stat_subnodes.at("mmcm_sticky").value();
226
227// mon_data.pll_ok = stat_subnodes.at("pll_ok").value();
228// mon_data.pll_sticky = stat_subnodes.at("pll_sticky").value();
229
230// mon_data.active_sfp_mux = ctrl_subnodes.at("inmux").value();
231
232// //mon_data.sfp_los_flags = read_sfp_los_flags();
233// //mon_data.sfp_fault_flags = read_sfp_fault_flags();
234// }
235//-----------------------------------------------------------------------------
236
237//-----------------------------------------------------------------------------
238// void
239// FIBV2IONode::get_info(opmonlib::InfoCollector& ci, int level) const
240// {
241
242// if (level >= 2) {
243// timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
244// get_pll()->get_info(pll_mon_data);
245// ci.add(pll_mon_data);
246
247// for (uint i=0; i < 8; ++i)
248// {
249// opmonlib::InfoCollector sfp_ic;
250
251// std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(i);
252// auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
253
254// try
255// {
256// sfp->get_info(sfp_ic, level);
257// }
258// catch (timing::SFPUnreachable& e)
259// {
260// // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
261// TLOG_DEBUG(2) << "Failed to communicate with SFP " << i << " on I2C switch channel " << (1UL << i) << " on i2c bus" << m_sfp_i2c_buses.at(0);
262// continue;
263// }
264// ci.add("sfp_"+std::to_string(i),sfp_ic);
265// }
266// }
267// if (level >= 1) {
268// timinghardwareinfo::TimingFIBMonitorData mon_data;
269// this->get_info(mon_data);
270// ci.add(mon_data);
271// }
272// }
273//-----------------------------------------------------------------------------
274} // namespace timing
275} // namespace dunedaq
#define ERS_HERE
Class for the FIB board.
std::string get_pll_status(bool print_out=false) const override
Print status of on-board PLL.
void validate_sfp_id(uint32_t sfp_id) const
Get the PLL chip.
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_status(bool print_out=false) const override
Get status string, optionally print.
void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override
Switch on or off the SFP tx laser via the I2C IO expander controlling the sfp tx disable pin....
void configure_pll(const std::string &clock_config_file="") const override
Configure clock chip.
std::string get_sfp_status(uint32_t sfp_id, bool print_out=false) const override
Print status of on-board SFP.
void reset_pll() const override
Reset PLL.
void reset(const ClockSource &clock_source) const override
Reset IO, with clock file look up.
float read_board_temperature() const
Read data from on-board temperature monitor.
std::string get_uid_address_parameter_name() const override
Get the UID address parameter name.
void get_info(timinghardwareinfo::TimingPLLMonitorData &mon_data) const override
Base class for timing IO nodes.
Definition IONode.hpp:44
virtual void write_soft_reset_register() const
Write soft reset register.
Definition IONode.cpp:287
const std::string m_pll_i2c_bus
Definition IONode.hpp:211
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
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
The DUNE-DAQ namespace.
Definition DataStore.hpp:57