DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
GIBIONode.cpp
Go to the documentation of this file.
1
10#include "timing/LM75Node.hpp"
11
12#include <string>
13#include <math.h>
14
15namespace dunedaq {
16namespace timing {
17
18UHAL_REGISTER_DERIVED_NODE(GIBIONode)
19
20//-----------------------------------------------------------------------------
21GIBIONode::GIBIONode(const uhal::Node& node)
22 : IONode(node, "i2c", "i2c", { "PLL" }, { "PLL", "SFP CDR 0", "SFP CDR 1", "SFP CDR 2", "SFP CDR 3", "SFP CDR 4", "SFP CDR 5", "10 MHz" }, { "i2c", "i2c", "i2c", "i2c", "i2c", "i2c" })
23{
24}
25//-----------------------------------------------------------------------------
26
27//-----------------------------------------------------------------------------
28GIBIONode::GIBIONode(const uhal::Node& node,
29 std::string uid_i2c_bus,
30 std::string pll_i2c_bus,
31 std::string pll_i2c_device,
32 std::vector<std::string> clock_names,
33 std::vector<std::string> sfp_i2c_buses)
34 : IONode(node, uid_i2c_bus, pll_i2c_bus, pll_i2c_device, clock_names, sfp_i2c_buses)
35{
36}
37//-----------------------------------------------------------------------------
38
39//-----------------------------------------------------------------------------
41//-----------------------------------------------------------------------------
42
43//-----------------------------------------------------------------------------
44std::string
46{
47 return "UID_PROM";
48}
49//-----------------------------------------------------------------------------
50
51//-----------------------------------------------------------------------------
52std::string
53GIBIONode::get_status(bool print_out) const
54{
55 std::stringstream status;
56
57 auto subnodes = read_sub_nodes(getNode("csr.stat"));
58 status << format_reg_table(subnodes, "GIB IO state");
59
60 auto subnodes_2 = read_sub_nodes(getNode("csr.ctrl"));
61 status << format_reg_table(subnodes_2, "GIB IO control");
62
63 uint8_t sfp_los = read_sfps_los();
64 uint8_t sfp_fault = read_sfps_fault();
65
66 std::vector<std::string> sfp_vec;
67 std::vector<uint8_t> los_vec;
68 std::vector<uint8_t> fault_vec;
69
70 for (int i=0; i<get_num_sfps(); i++) {
71 sfp_vec.push_back(to_string(i));
72 // L is 0x4C, H is L - 4
73 los_vec.push_back(0x4C - 4*((sfp_los >> i) & 1));
74 fault_vec.push_back(0x4C - 4*((sfp_fault >> i) & 1));
75 }
76
77 status << "------IO expander----" << std::endl;
78 status << "SFP: " << vec_fmt(sfp_vec) << std::endl;
79 status << "LOS: " << vec_fmt(los_vec) << std::endl;
80 status << "Fault: " << vec_fmt(fault_vec) << std::endl;
81
82 status << "Board temperature: " << read_board_temperature() << " [C]" << std::endl;
83
84 if (print_out)
85 TLOG() << std::endl << status.str();
86 return status.str();
87}
88//-----------------------------------------------------------------------------
89
90//-----------------------------------------------------------------------------
91std::unique_ptr<const SI534xSlave>
93{
94 // enable pll channel 0 only
97}
98//-----------------------------------------------------------------------------
99
100//-----------------------------------------------------------------------------
101std::string
102GIBIONode::get_hardware_info(bool print_out) const
103{
104 // enable pll/uid channel 0 only
106 return IONode::get_hardware_info(print_out);
107}
108//-----------------------------------------------------------------------------
109
110//-----------------------------------------------------------------------------
111void
113{
114 // enclustra i2c switch stuff
116 if (carrier_type == kCarrierEnclustraA35) {
117 try {
118 getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
119 } catch (const std::exception& e) {
120 ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
121 }
122 }
123
124 // Disable ICs
125 //getNode("csr.ctrl.i2c_sw_rst").write(0x1);
126 //getNode("csr.ctrl.i2c_exten_rst").write(0x1);
127 //getNode("csr.ctrl.clk_gen_rst").write(0x1);
128 //getClient().dispatch();
129
130 // Enable ICs
131 getNode("csr.ctrl.i2c_sw_rst").write(0x0);
132 getNode("csr.ctrl.i2c_exten_rst").write(0x0);
133 getNode("csr.ctrl.clk_gen_rst").write(0x0);
134 getClient().dispatch();
135
137}
138//-----------------------------------------------------------------------------
139
140//-----------------------------------------------------------------------------
141void
142GIBIONode::reset(const std::string& clock_config_file) const
143{
144 // Clear IPBus regs
145 soft_reset();
146
147 // In case this method is called directly, TODO refactor
149
150 getNode("csr.ctrl.gps_clk_en").write(0x0);
151
152 // Set filter to full bandwidth mode A = B = 0x0
153 getNode("csr.ctrl.gps_clk_fltr_a").write(0x0);
154 getNode("csr.ctrl.gps_clk_fltr_b").write(0x0);
155 getClient().dispatch();
156
157 // Upload config file to PLL
158 configure_pll(clock_config_file);
159
161
162 // reset dts logic
163 getNode("csr.ctrl.rst").write(0x1);
164 getClient().dispatch();
165 getNode("csr.ctrl.rst").write(0x0);
166 getClient().dispatch();
167
168 TLOG() << "Reset done";
169}
170//-----------------------------------------------------------------------------
171
172//-----------------------------------------------------------------------------
173void
175{
176 auto sfp_expander_0 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander0");
177 auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
178
179 // Set invert registers to default for both (0,1) banks
180 sfp_expander_0->set_inversion(0, 0x00);
181 sfp_expander_0->set_inversion(1, 0x00);
182 sfp_expander_1->set_inversion(0, 0x00);
183 sfp_expander_1->set_inversion(1, 0x00);
184
185 // 0: pin set as output, 1: pin set as input
186 sfp_expander_0->set_io(0, 0xff); // set all pins of bank 0 as inputs
187 sfp_expander_0->set_io(1, 0xff); // set all pins of bank 1 as inputs
188
189 sfp_expander_1->set_io(0, 0xff); // set all pins of bank 0 as inputs
190 sfp_expander_1->set_io(1, 0x00); // set all pins of bank 1 as outputs
191
192 // Set SFP disable
193 // Set tx disable pins low, i.e. enable the pins given in the bitmap
194 // (different between v1 and v2/3)
195 sfp_expander_1->set_outputs(1, get_sfp_tx_disable_bitmap());
196}
197//-----------------------------------------------------------------------------
198
199//-----------------------------------------------------------------------------
200void
202{
203 getNode("csr.ctrl.clk_gen_rst").write(0x1);
204 getNode("csr.ctrl.clk_gen_rst").write(0x0);
205}
206//-----------------------------------------------------------------------------
207
208//-----------------------------------------------------------------------------
209std::string
210GIBIONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
211 std::stringstream status;
212
213 validate_sfp_id(sfp_id);
214
215 uint8_t i2c_mux_bitmask = 1UL << (sfp_id+1);
216
217 set_i2c_mux_channels(i2c_mux_bitmask);
218
219 auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
220
221 status << "SFP " << sfp_id << ":" << std::endl;
222 status << sfp->get_status();
223
224 if (print_out)
225 TLOG() << status.str();
226
227 return status.str();
228}
229//-----------------------------------------------------------------------------
230
231//-----------------------------------------------------------------------------
232uint32_t
233GIBIONode::read_io_expanders() const { // NOLINT(build/unsigned)
234 auto sfp_expander_0 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander0");
235 auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
236
237 uint32_t expander_bits = sfp_expander_1->read_inputs(0);
238 expander_bits = (expander_bits << 8) + sfp_expander_0->read_inputs(1);
239 expander_bits = (expander_bits << 8) + sfp_expander_0->read_inputs(0);
240
241 return expander_bits;
242}
243//-----------------------------------------------------------------------------
244
245//-----------------------------------------------------------------------------
246uint8_t
247GIBIONode::read_sfps_los() const { // NOLINT(build/unsigned)
248 uint32_t expander_bits = read_io_expanders();
249
250 uint8_t los_bits = 0x00;
251
252 for (uint8_t sfp = 0; sfp<6; sfp++) {
253 // Each SFP has 4 bits, the 3rd bit is the LOS
254 // Adds the SFPs in inverse order
255 los_bits = (los_bits << 1) + ((expander_bits >> (2 + 20 - 4*sfp)) & 1);
256 }
257
258 return los_bits;
259}
260//-----------------------------------------------------------------------------
261
262//-----------------------------------------------------------------------------
263uint8_t
264GIBIONode::read_sfps_fault() const { // NOLINT(build/unsigned)
265 uint32_t expander_bits = read_io_expanders();
266
267 uint8_t fault_bits = 0x00;
268
269 for (uint8_t sfp = 0; sfp<6; sfp++) {
270 // Each SFP has 4 bits, the 4th bit is the fault
271 // Adds the SFPs in inverse order
272 fault_bits = (fault_bits << 1) + ((expander_bits >> (3 + 20 - 4*sfp)) & 1);
273 }
274
275 return fault_bits;
276}
277//-----------------------------------------------------------------------------
278
279//-----------------------------------------------------------------------------
280bool
282{
283 std::stringstream status;
284
285 auto states = read_sub_nodes(getNode("csr.stat"));
286 bool pll_lol = states.find("clk_gen_lol")->second.value();
287 bool pll_interrupt = states.find("clk_gen_intr")->second.value();
288 bool mmcm_ok = states.find("mmcm_ok")->second.value();
289 bool mmcm_10_ok = states.find("mmcm_ok")->second.value();
290
291 TLOG_DEBUG(5) << "pll lol: " << pll_lol << ", pll intr: " << pll_interrupt
292 << ", mmcm ok: " << mmcm_ok << ", mmcm 10MHz ok: " << mmcm_10_ok;
293
294 return !pll_lol && mmcm_ok && mmcm_10_ok;
295}
296//-----------------------------------------------------------------------------
297
298//-----------------------------------------------------------------------------
299void
300GIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
301 validate_sfp_id(sfp_id);
302
303 auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
304 sfp->switch_soft_tx_control_bit(turn_on);
305}
306//-----------------------------------------------------------------------------
307
308//-----------------------------------------------------------------------------
309void
310GIBIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
311 validate_sfp_id(sfp_id);
312
313 auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
314 uint8_t current_sfp_tx_control_flags = sfp_expander_1->read_outputs_config(1); // NOLINT(build/unsigned)
315
316 uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
317 if (turn_on)
318 {
319 new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
320 }
321 else
322 {
323 new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
324 }
325
326 sfp_expander_1->set_outputs(1, new_sfp_tx_control_flags);
327}
328//-----------------------------------------------------------------------------
329
330//-----------------------------------------------------------------------------
331//void
332//GIBIONode::get_info(timinghardwareinfo::TimingGIBMonitorData& mon_data) const
333//{
334 // TODO
335//}
336//-----------------------------------------------------------------------------
337
338//-----------------------------------------------------------------------------
339// void
340// GIBIONode::get_info(opmonlib::InfoCollector& /*ci*/, int /*level*/) const
341// {
342// // TO DO
343// }
344//-----------------------------------------------------------------------------
345
346//-----------------------------------------------------------------------------
347uint8_t
348GIBIONode::get_sfp_tx_disable_bitmap() const { // NOLINT(build/unsigned)
349 // First 6 bits are tx disable on GIBv1
350 return 0xC0;
351}
352//-----------------------------------------------------------------------------
353
354//-----------------------------------------------------------------------------
355uint8_t
356GIBIONode::get_num_sfps() const { // NOLINT(build/unsigned)
357 // 6 SFPs on GIBv1
358 return 6;
359}
360//-----------------------------------------------------------------------------
361
362//-----------------------------------------------------------------------------
363void
364GIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
365 // number of sfps on board defined by get_num_sfps
366 if (sfp_id >= get_num_sfps()) {
367 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
368 }
369}
370//-----------------------------------------------------------------------------
371
372//-----------------------------------------------------------------------------
373void
374GIBIONode::set_i2c_mux_channels(uint8_t mux_channel_bitmask) const { // NOLINT(build/unsigned)
375
376 uint8_t mux_channel_config = mux_channel_bitmask & 0x7f;
377
378 auto i2c_bus = getNode<I2CMasterNode>("i2c");
379 i2c_bus.write_i2cPrimitive(0x70, {mux_channel_config});
380}
381//-----------------------------------------------------------------------------
382
383//-----------------------------------------------------------------------------
384float
386{
387 auto temp_mon = get_i2c_device<LM75Node>(m_pll_i2c_bus, "TEMP_MON");
388 return temp_mon->read_temperature();
389}
390//-----------------------------------------------------------------------------
391} // namespace timing
392} // namespace dunedaq
#define ERS_HERE
Class for the timing FMC board.
Definition GIBIONode.hpp:33
void switch_sfp_tx(uint32_t sfp_id, bool turn_on) const override
control tx laser of on-board SFP softly (I2C command)
virtual uint8_t read_sfps_fault() const
Retrive SFP fault status for all SFPs.
void set_i2c_mux_channels(uint8_t mux_channel_bitmask) const
Fill hardware monitoring structure.
void reset(const std::string &clock_config_file) const override
Reset GIB IO.
void set_up_io_infrastructure() const override
Set up i2c buses, enable ICs.
std::unique_ptr< const SI534xSlave > get_pll() const override
GET PLL I2C interface.
Definition GIBIONode.cpp:92
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)
virtual uint8_t get_num_sfps() const
virtual uint32_t read_io_expanders() const
Read the contents of the IO expanders.
void validate_sfp_id(uint32_t sfp_id) const
std::string get_hardware_info(bool print_out) const override
Print hardware information.
void reset_pll() const override
Reset PLL.
std::string get_uid_address_parameter_name() const override
Get the UID address parameter name.
Definition GIBIONode.cpp:45
GIBIONode(const uhal::Node &node)
Definition GIBIONode.cpp:21
void configure_expander() const
Configure the GIB expander.
std::string get_sfp_status(uint32_t sfp_id, bool print_out=false) const override
Print status of on-board SFP.
std::string get_status(bool print_out=false) const override
Get status string, optionally print.
Definition GIBIONode.cpp:53
virtual uint8_t read_sfps_los() const
Retrive SFP LOS status for all SFPs.
bool clocks_ok() const override
Clocks ready?
virtual uint8_t get_sfp_tx_disable_bitmap() const
float read_board_temperature() const
Read board temp.
Base class for timing IO nodes.
Definition IONode.hpp:44
const std::string m_pll_i2c_bus
Definition IONode.hpp:216
const std::string m_pll_i2c_device
Definition IONode.hpp:217
virtual uint32_t read_carrier_type() const
Read the word identifying the FPFA carrier board.
Definition IONode.cpp:58
virtual std::string get_hardware_info(bool print_out=false) const
Print hardware information.
Definition IONode.cpp:118
const std::string m_uid_i2c_bus
Definition IONode.hpp:215
virtual void soft_reset() const
Reset timing node.
Definition IONode.cpp:306
const std::vector< std::string > m_sfp_i2c_buses
Definition IONode.hpp:219
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
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 vec_fmt(const std::vector< T > &vec)
Definition toolbox.hxx:382
std::string to_string(const T &v)
Definition toolbox.hxx:49
std::string format_reg_value(T reg_value, uint32_t base)
Definition toolbox.hxx:117
Including Qt Headers.
void warning(const Issue &issue)
Definition ers.hpp:115