DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
IONode.cpp
Go to the documentation of this file.
1
9#include "timing/IONode.hpp"
10
11#include "logging/Logging.hpp"
12
13#include <map>
14#include <memory>
15#include <string>
16#include <utility>
17#include <vector>
18
19namespace dunedaq {
20namespace timing {
21
22// UHAL_REGISTER_DERIVED_NODE(IONode);
23
24//-----------------------------------------------------------------------------
25IONode::IONode(const uhal::Node& node,
26 std::string uid_i2c_bus,
27 std::string pll_i2c_bus,
28 std::string pll_i2c_device,
29 std::vector<std::string> clock_names,
30 std::vector<std::string> sfp_i2c_buses)
31 : TimingNode(node)
32 , m_uid_i2c_bus(uid_i2c_bus)
33 , m_pll_i2c_bus(pll_i2c_bus)
34 , m_pll_i2c_device(pll_i2c_device)
35 , m_clock_names(clock_names)
36 , m_sfp_i2c_buses(sfp_i2c_buses)
37// mPLL (new SI534xSlave( getNode<I2CMasterNode>(m_pll_i2c_bus)& ,
38// getNode<I2CMasterNode>(m_pll_i2c_bus).get_slave_address(pll_i2c_device) ))
39{}
40//-----------------------------------------------------------------------------
41
42//-----------------------------------------------------------------------------
44//-----------------------------------------------------------------------------
45
46//-----------------------------------------------------------------------------
47uint32_t // NOLINT(build/unsigned)
49{
50 uhal::ValWord<uint32_t> board_type = getNode("config.board_type").read(); // NOLINT(build/unsigned)
51 getClient().dispatch();
52 return board_type.value();
53}
54//-----------------------------------------------------------------------------
55
56//-----------------------------------------------------------------------------
57uint32_t // NOLINT(build/unsigned)
59{
60 uhal::ValWord<uint32_t> carrier_type = getNode("config.carrier_type").read(); // NOLINT(build/unsigned)
61 getClient().dispatch();
62 return carrier_type.value();
63}
64//-----------------------------------------------------------------------------
65
66//-----------------------------------------------------------------------------
67uint32_t // NOLINT(build/unsigned)
69{
70 uhal::ValWord<uint32_t> design_type = getNode("config.design_type").read(); // NOLINT(build/unsigned)
71 getClient().dispatch();
72 return design_type.value();
73}
74//-----------------------------------------------------------------------------
75
76//-----------------------------------------------------------------------------
77uint32_t // NOLINT(build/unsigned)
79{
80 uhal::ValWord<uint32_t> firmware_frequency = getNode("config.clock_frequency").read(); // NOLINT(build/unsigned)
81 getClient().dispatch();
82 return firmware_frequency.value();
83}
84//-----------------------------------------------------------------------------
85
86//-----------------------------------------------------------------------------
87uint64_t // NOLINT(build/unsigned)
89{
90
91 uint64_t uid = 0; // NOLINT(build/unsigned)
92 std::vector<uint8_t> uid_values = // NOLINT(build/unsigned)
93 getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave(get_uid_address_parameter_name()).read_i2cArray(0xfa, 6);
94
95 for (uint8_t i = 0; i < uid_values.size(); ++i) { // NOLINT(build/unsigned)
96 uid = (uid << 8) | uid_values.at(i);
97 }
98 return uid;
99}
100//-----------------------------------------------------------------------------
101
102//-----------------------------------------------------------------------------
105{
106 auto uid = read_board_uid();
107 try {
108 return get_board_uid_revision_map().at(uid);
109 } catch (const std::out_of_range& e) {
110 ers::warning(UnknownBoardUID(ERS_HERE, format_reg_value(uid), e));
112 }
113}
114//-----------------------------------------------------------------------------
115
116//-----------------------------------------------------------------------------
117std::string
118IONode::get_hardware_info(bool print_out) const
119{
120 std::stringstream info;
122 const BoardRevision board_revision = get_board_revision();
125 const double firmware_frequency = read_firmware_frequency()/1e6;
126
127 std::vector<std::pair<std::string, std::string>> hardware_info;
128
129 try {
130 hardware_info.push_back(std::make_pair("Board type", get_board_type_map().at(board_type)));
131 } catch (const std::out_of_range& e) {
132 ers::error(MissingBoardTypeMapEntry(ERS_HERE, format_reg_value(board_type), e));
133 }
134
135 try {
136 hardware_info.push_back(std::make_pair("Board revision", get_board_revision_map().at(board_revision)));
137 } catch (const std::out_of_range& e) {
138 ers::error(MissingBoardRevisionMapEntry(ERS_HERE, format_reg_value(board_revision), e));
139 }
140
141 hardware_info.push_back(std::make_pair("Board UID", format_reg_value(read_board_uid())));
142
143 try {
144 hardware_info.push_back(std::make_pair("Carrier type", get_carrier_type_map().at(carrier_type)));
145 } catch (const std::out_of_range& e) {
146 ers::error(MissingCarrierTypeMapEntry(ERS_HERE, format_reg_value(carrier_type), e));
147 }
148
149 try {
150 hardware_info.push_back(std::make_pair("Design type", get_design_type_map().at(design_type)));
151 } catch (const std::out_of_range& e) {
152 ers::error(MissingDesignTypeMapEntry(ERS_HERE, format_reg_value(design_type), e));
153 }
154
155 hardware_info.push_back(std::make_pair("Firmware frequency [MHz]", std::to_string(firmware_frequency)));
156
157 info << format_reg_table(hardware_info, "Hardware info", { "", "" });
158
159 if (print_out)
160 TLOG() << info.str();
161 return info.str();
162}
163//-----------------------------------------------------------------------------
164
165//-----------------------------------------------------------------------------
166std::string
168{
169 std::string config_file;
170 std::stringstream clock_config_key;
171
173// const BoardRevision board_revision = get_board_revision();
176 //const uint32_t firmware_frequency = read_firmware_frequency(); // NOLINT(build/unsigned)
177
178 try {
179 clock_config_key << get_board_type_map().at(board_type) << "_";
180 } catch (const std::out_of_range& e) {
181 throw MissingBoardTypeMapEntry(ERS_HERE, format_reg_value(board_type), e);
182 }
183
184 // enclustra i2c switch stuff
185 if (carrier_type == kCarrierEnclustraA35) {
186 try {
187 getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
188 } catch (const std::exception& e) {
189 ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
190 }
191 }
192
193 auto pll = get_pll();
194 auto pll_model = pll->read_device_version();
195 clock_config_key << std::hex << pll_model;
196
197// try {
198// clock_config_key = clock_config_key + get_carrier_type_map().at(carrier_type) + "_";
199// } catch (const std::out_of_range& e) {
200// throw MissingCarrierTypeMapEntry(ERS_HERE, format_reg_value(carrier_type), e);
201// }
202
203 try {
204 clock_config_key << "_" << get_design_type_map().at(design_type);
205 } catch (const std::out_of_range& e) {
206 throw MissingDesignTypeMapEntry(ERS_HERE, format_reg_value(design_type), e);
207 }
208
209 clock_config_key << "_" << clock_source_to_string(clock_source);
210
211 TLOG_DEBUG(0) << "Using pll config key: " << clock_config_key.str();
212
213 try {
214 config_file = get_clock_config_map().at(clock_config_key.str());
215 } catch (const std::out_of_range& e) {
216 throw ClockConfigNotFound(ERS_HERE, clock_config_key.str(), e);
217 }
218
219 TLOG_DEBUG(0) << "PLL config file: " << config_file << " from key: " << clock_config_key.str();
220
221 const char* env_var_char = std::getenv("TIMING_SHARE");
222
223 if (env_var_char == nullptr) {
224 throw EnvironmentVariableNotSet(ERS_HERE, "TIMING_SHARE");
225 }
226
227 std::string env_var(env_var_char);
228
229 std::string full_pll_config_file_path = env_var + "/config/etc/clock/" + config_file;
230
231 TLOG_DEBUG(0) << "Full PLL config file path: " << full_pll_config_file_path;
232
233 return full_pll_config_file_path;
234}
235//-----------------------------------------------------------------------------
236
237//-----------------------------------------------------------------------------
238std::unique_ptr<const SI534xSlave>
243//-----------------------------------------------------------------------------
244
245//-----------------------------------------------------------------------------
246void
247IONode::configure_pll(const std::string& clock_config_file) const
248{
249 auto pll = get_pll();
250
251 TLOG() << "PLL configuration file : " << clock_config_file;
252
253 uint32_t si_pll_version = pll->read_device_version(); // NOLINT(build/unsigned)
254 TLOG_DEBUG(0) << "Configuring PLL : SI" << format_reg_value(si_pll_version);
255
256 pll->configure(clock_config_file);
257
258 TLOG_DEBUG(0) << "PLL configuration id : " << pll->read_config_id();
259}
260//-----------------------------------------------------------------------------
261
262//-----------------------------------------------------------------------------
263std::vector<double>
265{
266 return getNode<FrequencyCounterNode>("freq").measure_frequencies(m_clock_names.size());
267}
268//-----------------------------------------------------------------------------
269
270//-----------------------------------------------------------------------------
271std::string
273{
274 std::stringstream table;
275 std::vector<double> frequencies = read_clock_frequencies();
276 for (uint8_t i = 0; i < frequencies.size(); ++i) { // NOLINT(build/unsigned)
277 table << m_clock_names.at(i) << " freq: " << std::setprecision(12) << frequencies.at(i) << std::endl;
278 }
279 // TODO add freq validation Stoyan Trilov stoyan.trilov@cern.ch
280 if (print_out)
281 TLOG() << table.str();
282 return table.str();
283}
284//-----------------------------------------------------------------------------
285
286//-----------------------------------------------------------------------------
287std::string
288IONode::get_pll_status(bool print_out) const
289{
290 return get_pll()->get_status(print_out);
291}
292//-----------------------------------------------------------------------------
293
294//-----------------------------------------------------------------------------
295void
297{
298 getNode("csr.ctrl.soft_rst").write(0x1);
299 getClient().dispatch();
300}
301//-----------------------------------------------------------------------------
302
303//-----------------------------------------------------------------------------
304void
306{
308 TLOG_DEBUG(0) << "Soft reset done";
309}
310//-----------------------------------------------------------------------------
311
312//-----------------------------------------------------------------------------
313void
314IONode::reset(const ClockSource& clock_source) const
315{
316 // Find the right pll config file
317 std::string clock_config = get_full_clock_config_file_path(clock_source);
318 reset(clock_config);
319}
320//-----------------------------------------------------------------------------
321
322//-----------------------------------------------------------------------------
323std::string
324IONode::get_sfp_status(uint32_t sfp_id, bool print_out) const // NOLINT(build/unsigned)
325{
326 std::stringstream status;
327 std::string sfp_i2c_bus;
328 try {
329 sfp_i2c_bus = m_sfp_i2c_buses.at(sfp_id);
330 } catch (const std::out_of_range& e) {
331 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id), e);
332 }
333 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
334 status << sfp->get_status();
335 if (print_out)
336 TLOG() << status.str();
337 return status.str();
338}
339//-----------------------------------------------------------------------------
340
341//-----------------------------------------------------------------------------
342void
343IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned)
344{
345 std::string sfp_i2c_bus;
346 try {
347 sfp_i2c_bus = m_sfp_i2c_buses.at(sfp_id);
348 } catch (const std::out_of_range& e) {
349 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id), e);
350 }
351 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
352 sfp->switch_soft_tx_control_bit(turn_on);
353}
354//-----------------------------------------------------------------------------
355
356} // namespace timing
357} // namespace dunedaq
#define ERS_HERE
virtual uint32_t read_board_type() const
Read the word identifying the timing board.
Definition IONode.cpp:48
virtual void write_soft_reset_register() const
Write soft reset register.
Definition IONode.cpp:296
virtual void switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const
control tx laser of on-board SFP softly (I2C command)
Definition IONode.cpp:343
virtual void reset(const std::string &clock_config_file) const =0
Reset timing node.
virtual std::vector< double > read_clock_frequencies() const
Read frequencies of on-board clocks.
Definition IONode.cpp:264
virtual BoardRevision get_board_revision() const
Read the word identifying the timing board.
Definition IONode.cpp:104
const std::string m_pll_i2c_bus
Definition IONode.hpp:201
IONode(const uhal::Node &node, std::string uid_i2c_bus, std::string pll_i2c_bus, std::string pll_i2c_device, std::vector< std::string > clock_names, std::vector< std::string > sfp_i2c_buses)
Definition IONode.cpp:25
const std::string m_pll_i2c_device
Definition IONode.hpp:202
virtual uint32_t read_carrier_type() const
Read the word identifying the FPFA carrier board.
Definition IONode.cpp:58
static const std::map< std::string, std::string > & get_clock_config_map()
Definition IONode.hpp:195
virtual std::string get_sfp_status(uint32_t sfp_id, bool print_out=false) const
Print status of on-board SFP.
Definition IONode.cpp:324
virtual std::string get_hardware_info(bool print_out=false) const
Print hardware information.
Definition IONode.cpp:118
virtual std::string get_uid_address_parameter_name() const =0
Get the UID address parameter name.
virtual uint32_t read_design_type() const
Read the word identifying the firmware design in the FPGA.
Definition IONode.cpp:68
const std::string m_uid_i2c_bus
Definition IONode.hpp:200
virtual void soft_reset() const
Reset timing node.
Definition IONode.cpp:305
const std::vector< std::string > m_clock_names
Definition IONode.hpp:203
virtual std::string get_full_clock_config_file_path(const ClockSource &clock_source) const
Get the full config path.
Definition IONode.cpp:167
virtual std::unique_ptr< const SI534xSlave > get_pll() const
Get the PLL chip.
Definition IONode.cpp:239
static const std::map< uint64_t, BoardRevision > & get_board_uid_revision_map()
Definition IONode.hpp:193
virtual uint64_t read_board_uid() const
Read the word containing the timing board UID.
Definition IONode.cpp:88
virtual uint32_t read_firmware_frequency() const
Read the word identifying the frequency [units of Hz] of the firmware in the FPGA.
Definition IONode.cpp:78
static const std::map< DesignType, std::string > & get_design_type_map()
Definition IONode.hpp:194
virtual void configure_pll(const std::string &clock_config_file="") const
Configure clock chip.
Definition IONode.cpp:247
static const std::map< BoardRevision, std::string > & get_board_revision_map()
Definition IONode.hpp:192
virtual std::string get_clock_frequencies_table(bool print_out=false) const
Print frequencies of on-board clocks.
Definition IONode.cpp:272
static const std::map< BoardType, std::string > & get_board_type_map()
Definition IONode.hpp:188
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
virtual std::string get_pll_status(bool print_out=false) const
Print status of on-board PLL.
Definition IONode.cpp:288
static const std::map< CarrierType, std::string > & get_carrier_type_map()
Definition IONode.hpp:190
static std::string clock_source_to_string(const ClockSource &source)
Definition IONode.hpp:428
Base class for timing nodes.
#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
BoardType convert_value_to_board_type(uint32_t Board_type)
Definition toolbox.cpp:274
std::string format_reg_table(T data, std::string title, std::vector< std::string > headers)
Format reg-value table.
Definition toolbox.hxx:166
DesignType convert_value_to_design_type(uint32_t design_type)
Definition toolbox.cpp:300
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
void error(const Issue &issue)
Definition ers.hpp:81