Line data Source code
1 : /**
2 : * @file MIBV2IONode.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/MIBV2IONode.hpp"
10 :
11 : #include <string>
12 : #include <math.h>
13 :
14 : namespace dunedaq {
15 : namespace timing {
16 :
17 0 : UHAL_REGISTER_DERIVED_NODE(MIBV2IONode)
18 :
19 : //-----------------------------------------------------------------------------
20 0 : MIBV2IONode::MIBV2IONode(const uhal::Node& node)
21 0 : : IONode(node, "i2c", "i2c", { "PLL" }, { "OSC", "PLL", "EP 0", "EP 1", "EP 2" }, { "sfp0_i2c", "sfp1_i2c", "sfp2_i2c" })
22 : {
23 0 : }
24 : //-----------------------------------------------------------------------------
25 :
26 : //-----------------------------------------------------------------------------
27 0 : MIBV2IONode::~MIBV2IONode() {}
28 : //-----------------------------------------------------------------------------
29 :
30 : //-----------------------------------------------------------------------------
31 : std::string
32 0 : MIBV2IONode::get_uid_address_parameter_name() const
33 : {
34 0 : return "UID_PROM";
35 : }
36 : //-----------------------------------------------------------------------------
37 :
38 : //-----------------------------------------------------------------------------
39 : std::string
40 0 : MIBV2IONode::get_status(bool print_out) const
41 : {
42 0 : std::stringstream status;
43 :
44 0 : auto subnodes = read_sub_nodes(getNode("csr.stat"));
45 0 : status << format_reg_table(subnodes, "MIB IO state");
46 :
47 0 : if (print_out)
48 0 : TLOG() << std::endl << status.str();
49 0 : return status.str();
50 0 : }
51 : //-----------------------------------------------------------------------------
52 :
53 : //-----------------------------------------------------------------------------
54 : void
55 0 : MIBV2IONode::reset(const std::string& clock_config_file) const
56 : {
57 0 : write_soft_reset_register();
58 :
59 0 : millisleep(1000);
60 :
61 : // Upload config file to PLL
62 0 : configure_pll(clock_config_file);
63 :
64 : // Reset mmcm
65 0 : getNode("csr.ctrl.rst").write(0x1);
66 0 : getNode("csr.ctrl.rst").write(0x0);
67 :
68 0 : getClient().dispatch();
69 :
70 0 : TLOG() << "Reset done";
71 0 : }
72 : //-----------------------------------------------------------------------------
73 :
74 : //-----------------------------------------------------------------------------
75 : void
76 0 : MIBV2IONode::reset(const ClockSource& clock_source) const
77 : {
78 0 : IONode::reset(clock_source);
79 :
80 0 : switch_clock_source(clock_source);
81 0 : }
82 : //-----------------------------------------------------------------------------
83 :
84 : //-----------------------------------------------------------------------------
85 0 : void MIBV2IONode::reset_pll() const
86 : {
87 0 : }
88 : //-----------------------------------------------------------------------------
89 :
90 : //-----------------------------------------------------------------------------
91 : void
92 0 : MIBV2IONode::switch_clock_source(const ClockSource& clock_source) const
93 : {
94 0 : if (clock_source != kFreeRun)
95 : {
96 0 : getNode("csr.ctrl.pll_in_sel").write(clock_source);
97 0 : getClient().dispatch();
98 : }
99 0 : }
100 : //-----------------------------------------------------------------------------
101 :
102 : //-----------------------------------------------------------------------------
103 : std::string
104 0 : MIBV2IONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
105 0 : std::stringstream status;
106 :
107 0 : validate_sfp_id(sfp_id);
108 :
109 0 : auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
110 :
111 0 : status << "SFP " << sfp_id << ":" << std::endl;
112 0 : status << sfp->get_status();
113 :
114 0 : if (print_out)
115 0 : TLOG() << status.str();
116 :
117 0 : return status.str();
118 0 : }
119 : //-----------------------------------------------------------------------------
120 :
121 : //-----------------------------------------------------------------------------
122 : bool
123 0 : MIBV2IONode::clocks_ok() const
124 : {
125 0 : std::stringstream status;
126 :
127 0 : auto states = read_sub_nodes(getNode("csr.stat"));
128 0 : bool pll_ok = states.find("pll_ok")->second.value();
129 0 : bool mmcm_ok = states.find("mmcm_ok")->second.value();
130 :
131 0 : TLOG_DEBUG(5) << "pll ok: " << pll_ok << ", mmcm ok: " << mmcm_ok;
132 :
133 0 : return pll_ok && mmcm_ok;
134 0 : }
135 : //-----------------------------------------------------------------------------
136 :
137 : //-----------------------------------------------------------------------------
138 : void
139 0 : MIBV2IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
140 0 : validate_sfp_id(sfp_id);
141 :
142 0 : auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
143 0 : sfp->switch_soft_tx_control_bit(turn_on);
144 0 : }
145 : //-----------------------------------------------------------------------------
146 :
147 : //-----------------------------------------------------------------------------
148 : void
149 0 : MIBV2IONode::switch_sfp_tx(uint32_t /*sfp_id*/, bool /*turn_on*/) const // NOLINT(build/unsigned)
150 : {
151 : // TODO firmware support needed
152 : //validate_sfp_id(sfp_id);
153 :
154 : //uint8_t current_sfp_tx_control_flags = getNode("csr.ctrl.sfp_tx_disable").read(); // NOLINT(build/unsigned)
155 : //getClient().dispatch();
156 :
157 : //uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
158 : //if (turn_on)
159 : //{
160 : // new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
161 : //}
162 : //else
163 : //{
164 : // new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
165 : //}
166 :
167 : //getNode("csr.ctrl.sfp_tx_disable").write(new_sfp_tx_control_flags);
168 : //getClient().dispatch();
169 0 : }
170 : //-----------------------------------------------------------------------------
171 :
172 : //-----------------------------------------------------------------------------
173 : //void
174 : //MIBV2IONode::get_info(timinghardwareinfo::TimingMIBV2MonitorData& mon_data) const
175 : //{
176 : // TODO
177 : //}
178 : //-----------------------------------------------------------------------------
179 :
180 : //-----------------------------------------------------------------------------
181 : // void
182 : // MIBV2IONode::get_info(opmonlib::InfoCollector& /*ci*/, int /*level*/) const
183 : // {
184 : // // TO DO
185 : // }
186 : //-----------------------------------------------------------------------------
187 :
188 : //-----------------------------------------------------------------------------
189 : void
190 0 : MIBV2IONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
191 : // on this board we have 3 upstream SFPs
192 0 : if (sfp_id > 2) {
193 0 : throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
194 : }
195 0 : }
196 : //-----------------------------------------------------------------------------
197 :
198 : //-----------------------------------------------------------------------------
199 : void
200 0 : MIBV2IONode::validate_amc_slot(uint32_t amc_slot) const { // NOLINT(build/unsigned)
201 0 : if (amc_slot < 1 || amc_slot > 12) {
202 0 : throw InvalidAMCSlot(ERS_HERE, format_reg_value(amc_slot, 10));
203 : }
204 0 : }
205 : //-----------------------------------------------------------------------------
206 : } // namespace timing
207 : } // namespace dunedaq
|