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//-----------------------------------------------------------------------------
29//-----------------------------------------------------------------------------
30
31//-----------------------------------------------------------------------------
32std::string
34{
35 return "UID_PROM";
36}
37//-----------------------------------------------------------------------------
38
39//-----------------------------------------------------------------------------
40std::string
41GIBIONode::get_status(bool print_out) const
42{
43 std::stringstream status;
44
45 auto subnodes = read_sub_nodes(getNode("csr.stat"));
46 status << format_reg_table(subnodes, "GIB IO state");
47
48 auto subnodes_2 = read_sub_nodes(getNode("csr.ctrl"));
49 status << format_reg_table(subnodes_2, "GIB IO control");
50
51 status << "Board temperature: " << read_board_temperature() << " [C]" << std::endl;
52
53 if (print_out)
54 TLOG() << std::endl << status.str();
55 return status.str();
56}
57//-----------------------------------------------------------------------------
58
59//-----------------------------------------------------------------------------
60std::unique_ptr<const SI534xSlave>
62{
63 // enable pll channel 0 only
66}
67//-----------------------------------------------------------------------------
68
69//-----------------------------------------------------------------------------
70std::string
71GIBIONode::get_hardware_info(bool print_out) const
72{
73 // enable pll/uid channel 0 only
75 return IONode::get_hardware_info(print_out);
76}
77//-----------------------------------------------------------------------------
78
79//-----------------------------------------------------------------------------
80void
82{
83 // enclustra i2c switch stuff
85 if (carrier_type == kCarrierEnclustraA35) {
86 try {
87 getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
88 } catch (const std::exception& e) {
89 ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
90 }
91 }
92
93 // Reset I2C switch and expander, active low
94 getNode("csr.ctrl.i2c_sw_rst").write(0x0);
95 getNode("csr.ctrl.i2c_exten_rst").write(0x0);
96 getNode("csr.ctrl.clk_gen_rst").write(0x0);
97 getClient().dispatch();
98
99 millisleep(1);
100
101 // End reset
102 getNode("csr.ctrl.i2c_sw_rst").write(0x1);
103 getNode("csr.ctrl.i2c_exten_rst").write(0x1);
104 getNode("csr.ctrl.clk_gen_rst").write(0x1);
105 getClient().dispatch();
106
108}
109//-----------------------------------------------------------------------------
110
111//-----------------------------------------------------------------------------
112void
113GIBIONode::reset(const std::string& clock_config_file) const
114{
115 getNode("csr.ctrl.rst").write(0x1);
116 getNode("csr.ctrl.rst").write(0x0);
117 getClient().dispatch();
118
120
121 getNode("csr.ctrl.gps_clk_en").write(0x0);
122
123 // Set filter to full bandwidth mode A = B = 0x0
124 getNode("csr.ctrl.gps_clk_fltr_a").write(0x0);
125 getNode("csr.ctrl.gps_clk_fltr_b").write(0x0);
126 getClient().dispatch();
127
128 // Upload config file to PLL
129 configure_pll(clock_config_file);
130
131 auto sfp_expander_0 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander0");
132 auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
133
134 // Set invert registers to default for both (0,1) banks
135 sfp_expander_0->set_inversion(0, 0x00);
136 sfp_expander_0->set_inversion(1, 0x00);
137 sfp_expander_1->set_inversion(0, 0x00);
138 sfp_expander_1->set_inversion(1, 0x00);
139
140 // 0: pin set as output, 1: pin set as input
141 sfp_expander_0->set_io(0, 0xff); // set all pins of bank 0 as inputs
142 sfp_expander_0->set_io(1, 0xff); // set all pins of bank 1 as inputs
143
144 sfp_expander_1->set_io(0, 0xff); // set all pins of bank 0 as inputs
145 sfp_expander_1->set_io(1, 0x00); // set all pins of bank 1 as outputs
146
147 // Set SFP disable
148 // Set pins 1-6 low, i.e. enable SFP 1-6 (pins 7,8 unused)
149 sfp_expander_1->set_outputs(1, 0xC0);
150
151 TLOG() << "Reset done";
152}
153//-----------------------------------------------------------------------------
154
155//-----------------------------------------------------------------------------
156void
158{
159 getNode("csr.ctrl.clk_gen_rst").write(0x0);
160 getNode("csr.ctrl.clk_gen_rst").write(0x1);
161}
162//-----------------------------------------------------------------------------
163
164//-----------------------------------------------------------------------------
165std::string
166GIBIONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
167 std::stringstream status;
168
169 validate_sfp_id(sfp_id);
170
171 uint8_t i2c_mux_bitmask = 1UL << (sfp_id+1);
172
173 set_i2c_mux_channels(i2c_mux_bitmask);
174
175 auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
176
177 status << "SFP " << sfp_id << ":" << std::endl;
178 status << sfp->get_status();
179
180 if (print_out)
181 TLOG() << status.str();
182
183 return status.str();
184}
185//-----------------------------------------------------------------------------
186
187//-----------------------------------------------------------------------------
188bool
190{
191 std::stringstream status;
192
193 auto states = read_sub_nodes(getNode("csr.stat"));
194 bool pll_lol = states.find("clk_gen_lol")->second.value();
195 bool pll_interrupt = states.find("clk_gen_intr")->second.value();
196 bool mmcm_ok = states.find("mmcm_ok")->second.value();
197 bool mmcm_10_ok = states.find("mmcm_ok")->second.value();
198
199 TLOG_DEBUG(5) << "pll lol: " << pll_lol << ", pll intr: " << pll_interrupt
200 << ", mmcm ok: " << mmcm_ok << ", mmcm 10MHz ok: " << mmcm_10_ok;
201
202 return !pll_lol && mmcm_ok && mmcm_10_ok;
203}
204//-----------------------------------------------------------------------------
205
206//-----------------------------------------------------------------------------
207void
208GIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
209 validate_sfp_id(sfp_id);
210
211 auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
212 sfp->switch_soft_tx_control_bit(turn_on);
213}
214//-----------------------------------------------------------------------------
215
216//-----------------------------------------------------------------------------
217void
218GIBIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
219 validate_sfp_id(sfp_id);
220
221 auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
222 uint8_t current_sfp_tx_control_flags = sfp_expander_1->read_outputs_config(1); // NOLINT(build/unsigned)
223
224 uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
225 if (turn_on)
226 {
227 new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
228 }
229 else
230 {
231 new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
232 }
233
234 sfp_expander_1->set_outputs(1, new_sfp_tx_control_flags);
235}
236//-----------------------------------------------------------------------------
237
238//-----------------------------------------------------------------------------
239//void
240//GIBIONode::get_info(timinghardwareinfo::TimingGIBMonitorData& mon_data) const
241//{
242 // TODO
243//}
244//-----------------------------------------------------------------------------
245
246//-----------------------------------------------------------------------------
247// void
248// GIBIONode::get_info(opmonlib::InfoCollector& /*ci*/, int /*level*/) const
249// {
250// // TO DO
251// }
252//-----------------------------------------------------------------------------
253
254//-----------------------------------------------------------------------------
255void
256GIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
257 // on this board we have 6 SFPs
258 if (sfp_id > 5) {
259 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
260 }
261}
262//-----------------------------------------------------------------------------
263
264//-----------------------------------------------------------------------------
265void
266GIBIONode::set_i2c_mux_channels(uint8_t mux_channel_bitmask) const { // NOLINT(build/unsigned)
267
268 uint8_t mux_channel_config = mux_channel_bitmask & 0x7f;
269
270 auto i2c_bus = getNode<I2CMasterNode>("i2c");
271 i2c_bus.write_i2cPrimitive(0x70, {mux_channel_config});
272}
273//-----------------------------------------------------------------------------
274
275//-----------------------------------------------------------------------------
276float
278{
279 auto temp_mon = get_i2c_device<LM75Node>(m_pll_i2c_bus, "TEMP_MON");
280 return temp_mon->read_temperature();
281}
282//-----------------------------------------------------------------------------
283} // namespace timing
284} // 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)
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.
Definition GIBIONode.cpp:81
std::unique_ptr< const SI534xSlave > get_pll() const override
GET PLL I2C interface.
Definition GIBIONode.cpp:61
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
std::string get_hardware_info(bool print_out) const override
Print hardware information.
Definition GIBIONode.cpp:71
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:33
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:41
bool clocks_ok() const override
Clocks ready?
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:211
const std::string m_pll_i2c_device
Definition IONode.hpp:212
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:210
const std::vector< std::string > m_sfp_i2c_buses
Definition IONode.hpp:214
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 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