DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
TLUIONode.cpp
Go to the documentation of this file.
1
10
11#include <string>
12
13namespace dunedaq {
14namespace timing {
15
16UHAL_REGISTER_DERIVED_NODE(TLUIONode)
17
18//-----------------------------------------------------------------------------
19TLUIONode::TLUIONode(const uhal::Node& node)
20 : IONode(node, "i2c", "i2c", "SI5345", { "PLL" }, {})
21 , m_dac_devices({ "DAC1", "DAC2" })
22{}
23//-----------------------------------------------------------------------------
24
25//-----------------------------------------------------------------------------
27//-----------------------------------------------------------------------------
28
29//-----------------------------------------------------------------------------
30std::string
32{
33 return "UID_PROM";
34}
35//-----------------------------------------------------------------------------
36
37//-----------------------------------------------------------------------------
38std::string
39TLUIONode::get_status(bool print_out) const
40{
41 auto subnodes = read_sub_nodes(getNode("csr.stat"));
42 std::stringstream status;
43 status << format_reg_table(subnodes, "TLU IO state");
44
45 if (print_out)
46 TLOG() << status.str();
47 return status.str();
48}
49//-----------------------------------------------------------------------------
50
51//-----------------------------------------------------------------------------
52void
53TLUIONode::reset(const std::string& clock_config_file) const
54{
55 // Soft reset
57
58 millisleep(1000);
59
60 // Reset PLL and I2C
61 getNode("csr.ctrl.pll_rst").write(0x1);
62 getNode("csr.ctrl.pll_rst").write(0x0);
63
64 getNode("csr.ctrl.rst_i2c").write(0x1);
65 getNode("csr.ctrl.rst_i2c").write(0x0);
66
67 getClient().dispatch();
68
69 // enclustra i2c switch stuff
70 try {
71 getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
72 } catch (const std::exception& e) {
73 ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
74 }
75
76 // Upload config file to PLL
77 configure_pll(clock_config_file);
78
79 // Tweak the PLL swing
80 auto si_chip = get_pll();
81 si_chip->write_i2cArray(0x113, { 0x9, 0x33 });
82
83 // Reset mmcm
84 getNode("csr.ctrl.rst").write(0x1);
85 getNode("csr.ctrl.rst").write(0x0);
86 getClient().dispatch();
87
88 // configure tlu io expanders
89 auto ic_6 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
90 auto ic_7 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
91
92 // Bank 0
93 ic_6->set_inversion(0, 0x00);
94 ic_6->set_io(0, 0x00);
95 ic_6->set_outputs(0, 0x00);
96
97 // Bank 1
98 ic_6->set_inversion(1, 0x00);
99 ic_6->set_io(1, 0x00);
100 ic_6->set_outputs(1, 0x88);
101
102 // Bank 0
103 ic_7->set_inversion(0, 0x00);
104 ic_7->set_io(0, 0x00);
105 ic_7->set_outputs(0, 0xf0);
106
107 // Bank 1
108 ic_7->set_inversion(1, 0x00);
109 ic_7->set_io(1, 0x00);
110 ic_7->set_outputs(1, 0xf0);
111
112 // BI signals are NIM
113 uint32_t bi_signal_threshold = 0x589D; // NOLINT(build/unsigned)
114
115 configure_dac(0, bi_signal_threshold);
116 configure_dac(1, bi_signal_threshold);
117
118 TLOG_DEBUG(0) << "DAC1 and DAC2 set to " << std::hex << bi_signal_threshold;
119
120 TLOG() << "Reset done";
121}
122//-----------------------------------------------------------------------------
123
124//-----------------------------------------------------------------------------
126{
127}
128//-----------------------------------------------------------------------------
129
130//-----------------------------------------------------------------------------
131void
132TLUIONode::configure_dac(uint32_t dac_id, uint32_t dac_value, bool internal_ref) const // NOLINT(build/unsigned)
133{
134 std::string dac_device;
135 try {
136 dac_device = m_dac_devices.at(dac_id);
137 } catch (const std::out_of_range& e) {
138 throw InvalidDACId(ERS_HERE, format_reg_value(dac_id));
139 }
140 auto dac = get_i2c_device<DACSlave>(m_uid_i2c_bus, dac_device);
141 dac->set_interal_ref(internal_ref);
142 dac->set_dac(7, dac_value);
143}
144//-----------------------------------------------------------------------------
145
146//-----------------------------------------------------------------------------
147std::string
148TLUIONode::get_sfp_status(uint32_t /*sfp_id*/, bool /*print_out*/) const // NOLINT(build/unsigned)
149{
150 TLOG() << "TLU does not support SFP I2C";
151 return "";
152}
153//-----------------------------------------------------------------------------
154
155//-----------------------------------------------------------------------------
156bool
158{
159 std::stringstream status;
160
161 auto states = read_sub_nodes(getNode("csr.stat"));
162 //bool pll_ok = states.find("pll_ok")->second.value();
163 bool mmcm_ok = states.find("mmcm_ok")->second.value();
164
165 TLOG_DEBUG(5) << ", mmcm ok: " << mmcm_ok;
166
167 return mmcm_ok; // TODO for check pll lock when appropiate
168}
169//-----------------------------------------------------------------------------
170
171//-----------------------------------------------------------------------------
172void
173TLUIONode::switch_sfp_soft_tx_control_bit(uint32_t /*sfp_id*/, bool /*turn_on*/) const // NOLINT(build/unsigned)
174{
175 TLOG() << "TLU does not support SFP I2C";
176}
177//-----------------------------------------------------------------------------
178
179//-----------------------------------------------------------------------------
180void
181TLUIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned)
182{
183 validate_sfp_id(sfp_id);
184
185 getNode("csr.ctrl.sfp_tx_dis").write(turn_on);
186 getClient().dispatch();
187}
188//-----------------------------------------------------------------------------
189
190//-----------------------------------------------------------------------------
191void
192TLUIONode::validate_sfp_id(uint32_t sfp_id) const
193{ // NOLINT(build/unsigned)
194 // on this board we have 3 upstream SFPs
195 if (sfp_id != 0)
196 {
197 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
198 }
199}
200//-----------------------------------------------------------------------------
201
202//-----------------------------------------------------------------------------
203// void
204// TLUIONode::get_info(timinghardwareinfo::TimingTLUMonitorData& mon_data) const
205// {
206
207// auto subnodes = read_sub_nodes(getNode("csr.stat"));
208
209// mon_data.cdr_lol = subnodes.at("cdr_lol");
210// mon_data.cdr_los = subnodes.at("cdr_los");
211// mon_data.mmcm_ok = subnodes.at("mmcm_ok");
212// mon_data.mmcm_sticky = subnodes.at("mmcm_sticky");
213// mon_data.pll_ok = subnodes.at("pll_ok");
214// mon_data.pll_sticky = subnodes.at("pll_sticky");
215// mon_data.sfp_flt = subnodes.at("sfp_fault");
216// mon_data.sfp_los = subnodes.at("sfp_los");
217// }
218// //-----------------------------------------------------------------------------
219
220// //-----------------------------------------------------------------------------
221// void
222// TLUIONode::get_info(opmonlib::InfoCollector& ci, int level) const
223// {
224
225// if (level >= 2) {
226// timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
227// this->get_pll()->get_info(pll_mon_data);
228// ci.add(pll_mon_data);
229// }
230// if (level >= 1) {
231// timinghardwareinfo::TimingTLUMonitorData mon_data;
232// this->get_info(mon_data);
233// ci.add(mon_data);
234// }
235// }
236//-----------------------------------------------------------------------------
237
238} // namespace timing
239} // 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:287
const std::string m_uid_i2c_bus
Definition IONode.hpp:210
virtual std::unique_ptr< const SI534xSlave > get_pll() const
Get the PLL chip.
Definition IONode.cpp:230
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
Class for the TLU board.
Definition TLUIONode.hpp:34
void reset(const std::string &clock_config_file) const override
Reset IO node.
Definition TLUIONode.cpp:53
void switch_sfp_tx(uint32_t, bool) const override
Control tx laser of on-board SFP softly (I2C command)
void reset_pll() const override
Reset PLL.
void validate_sfp_id(uint32_t sfp_id) const
void configure_dac(uint32_t dac_id, uint32_t dac_value, bool internal_ref=false) const
Configure on-board DAC.
std::string get_status(bool print_out=false) const
Print the status of the timing node.
Definition TLUIONode.cpp:39
bool clocks_ok() const override
Clocks ready?
std::string get_uid_address_parameter_name() const override
Get the UID address parameter name.
Definition TLUIONode.cpp:31
void switch_sfp_soft_tx_control_bit(uint32_t, bool) 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
Print status of on-board SFP.
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
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