Line data Source code
1 : /**
2 : * @file FIBV2IONode.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/FIBV2IONode.hpp"
10 : #include "timing/LM75Node.hpp"
11 :
12 : #include <map>
13 : #include <string>
14 : #include <utility>
15 : #include <vector>
16 :
17 : namespace dunedaq {
18 : namespace timing {
19 :
20 0 : UHAL_REGISTER_DERIVED_NODE(FIBV2IONode)
21 :
22 : //-----------------------------------------------------------------------------
23 0 : FIBV2IONode::FIBV2IONode(const uhal::Node& aNode) :
24 0 : 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 0 : }
26 : //-----------------------------------------------------------------------------
27 :
28 :
29 : //-----------------------------------------------------------------------------
30 0 : FIBV2IONode::~FIBV2IONode() {
31 0 : }
32 : //-----------------------------------------------------------------------------
33 :
34 : //-----------------------------------------------------------------------------
35 : std::string
36 0 : FIBV2IONode::get_uid_address_parameter_name() const
37 : {
38 0 : return "UID_PROM";
39 : }
40 : //-----------------------------------------------------------------------------
41 :
42 : //-----------------------------------------------------------------------------
43 : void
44 0 : FIBV2IONode::configure_pll(const std::string& /*clock_config_file*/) const
45 : {
46 0 : TLOG() << "No text config for CDCLVD110";
47 0 : }
48 : //-----------------------------------------------------------------------------
49 :
50 : //-----------------------------------------------------------------------------
51 : std::string
52 0 : FIBV2IONode::get_status(bool print_out) const
53 : {
54 0 : std::stringstream status;
55 0 : auto subnodes = read_sub_nodes(getNode("csr.stat"));
56 0 : status << format_reg_table(subnodes, "FIB IO state") << std::endl;
57 :
58 0 : status << "Board temperature: " << read_board_temperature() << " [C]" << std::endl;
59 :
60 0 : if (print_out)
61 0 : TLOG() << status.str();
62 :
63 0 : return status.str();
64 0 : }
65 : //-----------------------------------------------------------------------------
66 :
67 : //-----------------------------------------------------------------------------
68 : void
69 0 : FIBV2IONode::reset(const ClockSource& clock_source) const {
70 :
71 : // Soft reset
72 0 : write_soft_reset_register();
73 :
74 0 : millisleep(1000);
75 :
76 0 : getNode("csr.ctrl.rst").write(0x1);
77 0 : getNode("csr.ctrl.rst").write(0x0);
78 :
79 0 : getClient().dispatch();
80 :
81 0 : getNode("csr.ctrl.clk_enable").write(0x0);
82 :
83 0 : if (clock_source == kInput0)
84 : {
85 0 : getNode("csr.ctrl.clk_select").write(0x0);
86 : }
87 0 : else if (clock_source == kInput1)
88 : {
89 0 : getNode("csr.ctrl.clk_select").write(0x1);
90 : }
91 : else
92 : {
93 : // TODO :throw something here
94 : }
95 :
96 0 : getClient().dispatch();
97 :
98 0 : TLOG() << "Reset done";
99 0 : }
100 : //-----------------------------------------------------------------------------
101 :
102 : //-----------------------------------------------------------------------------
103 0 : void FIBV2IONode::reset_pll() const
104 : {
105 0 : }
106 : //-----------------------------------------------------------------------------
107 :
108 :
109 : //-----------------------------------------------------------------------------
110 : std::string
111 0 : FIBV2IONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
112 0 : std::stringstream status;
113 :
114 0 : validate_sfp_id(sfp_id);
115 :
116 0 : std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
117 0 : auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
118 0 : status << "FIB V2 SFP " << sfp_id << ":" << std::endl;
119 0 : status << sfp->get_status();
120 :
121 0 : if (print_out)
122 0 : TLOG() << status.str();
123 :
124 0 : return status.str();
125 0 : }
126 : //-----------------------------------------------------------------------------
127 :
128 : //-----------------------------------------------------------------------------
129 : void
130 0 : FIBV2IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
131 0 : validate_sfp_id(sfp_id);
132 :
133 : // on this board the 8 downstream sfps have their own i2c bus
134 0 : std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
135 0 : auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
136 0 : sfp->switch_soft_tx_control_bit(turn_on);
137 0 : }
138 : //-----------------------------------------------------------------------------
139 :
140 : //-----------------------------------------------------------------------------
141 : void
142 0 : FIBV2IONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
143 :
144 0 : validate_sfp_id(sfp_id);
145 :
146 0 : auto sfp_tx_control_flags = getNode("csr.ctrl.sfp_tx_disable").read(); // NOLINT(build/unsigned)
147 0 : getClient().dispatch();
148 :
149 0 : uint8_t current_sfp_tx_control_flags=sfp_tx_control_flags.value();
150 0 : uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
151 :
152 0 : if (turn_on)
153 : {
154 0 : new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
155 : }
156 : else
157 : {
158 0 : new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
159 : }
160 :
161 0 : getNode("csr.ctrl.sfp_tx_disable").write(new_sfp_tx_control_flags);
162 0 : getClient().dispatch();
163 0 : }
164 : //-----------------------------------------------------------------------------
165 :
166 : //-----------------------------------------------------------------------------
167 : void
168 0 : FIBV2IONode::get_info(timinghardwareinfo::TimingPLLMonitorData& mon_data) const
169 : {
170 0 : mon_data.lol = false; // no monitoring of this in CDCLVD110
171 0 : mon_data.los = false;
172 0 : }
173 : //-----------------------------------------------------------------------------
174 :
175 : //-----------------------------------------------------------------------------
176 : std::string
177 0 : FIBV2IONode::get_pll_status(bool print_out) const
178 : {
179 0 : std::stringstream status;
180 0 : status << "No status yet for CDCLVD110 on FIBv2";
181 :
182 0 : if (print_out)
183 0 : TLOG() << status.str();
184 :
185 0 : return status.str();
186 0 : }
187 : //-----------------------------------------------------------------------------
188 :
189 : //-----------------------------------------------------------------------------
190 : float
191 0 : FIBV2IONode::read_board_temperature() const
192 : {
193 0 : auto temp_mon = get_i2c_device<LM75Node>(m_pll_i2c_bus, "TEMP_MON");
194 0 : return temp_mon->read_temperature();
195 0 : }
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 : //-----------------------------------------------------------------------------
207 : void
208 0 : FIBV2IONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
209 : // on this board we have 8 downstream SFPs
210 0 : if (sfp_id > 7) {
211 0 : throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
212 : }
213 0 : }
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
|