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 auto pll = get_pll();
185 auto pll_model = pll->read_device_version();
186 clock_config_key << std::hex << pll_model;
187
188// try {
189// clock_config_key = clock_config_key + get_carrier_type_map().at(carrier_type) + "_";
190// } catch (const std::out_of_range& e) {
191// throw MissingCarrierTypeMapEntry(ERS_HERE, format_reg_value(carrier_type), e);
192// }
193
194 try {
195 clock_config_key << "_" << get_design_type_map().at(design_type);
196 } catch (const std::out_of_range& e) {
197 throw MissingDesignTypeMapEntry(ERS_HERE, format_reg_value(design_type), e);
198 }
199
200 clock_config_key << "_" << clock_source_to_string(clock_source);
201
202 TLOG_DEBUG(0) << "Using pll config key: " << clock_config_key.str();
203
204 try {
205 config_file = get_clock_config_map().at(clock_config_key.str());
206 } catch (const std::out_of_range& e) {
207 throw ClockConfigNotFound(ERS_HERE, clock_config_key.str(), e);
208 }
209
210 TLOG_DEBUG(0) << "PLL config file: " << config_file << " from key: " << clock_config_key.str();
211
212 const char* env_var_char = std::getenv("TIMING_SHARE");
213
214 if (env_var_char == nullptr) {
215 throw EnvironmentVariableNotSet(ERS_HERE, "TIMING_SHARE");
216 }
217
218 std::string env_var(env_var_char);
219
220 std::string full_pll_config_file_path = env_var + "/config/etc/clock/" + config_file;
221
222 TLOG_DEBUG(0) << "Full PLL config file path: " << full_pll_config_file_path;
223
224 return full_pll_config_file_path;
225}
226//-----------------------------------------------------------------------------
227
228//-----------------------------------------------------------------------------
229std::unique_ptr<const SI534xSlave>
234//-----------------------------------------------------------------------------
235
236//-----------------------------------------------------------------------------
237void
238IONode::configure_pll(const std::string& clock_config_file) const
239{
240 auto pll = get_pll();
241
242 TLOG() << "PLL configuration file : " << clock_config_file;
243
244 uint32_t si_pll_version = pll->read_device_version(); // NOLINT(build/unsigned)
245 TLOG_DEBUG(0) << "Configuring PLL : SI" << format_reg_value(si_pll_version);
246
247 pll->configure(clock_config_file);
248
249 TLOG_DEBUG(0) << "PLL configuration id : " << pll->read_config_id();
250}
251//-----------------------------------------------------------------------------
252
253//-----------------------------------------------------------------------------
254std::vector<double>
256{
257 return getNode<FrequencyCounterNode>("freq").measure_frequencies(m_clock_names.size());
258}
259//-----------------------------------------------------------------------------
260
261//-----------------------------------------------------------------------------
262std::string
264{
265 std::stringstream table;
266 std::vector<double> frequencies = read_clock_frequencies();
267 for (uint8_t i = 0; i < frequencies.size(); ++i) { // NOLINT(build/unsigned)
268 table << m_clock_names.at(i) << " freq: " << std::setprecision(12) << frequencies.at(i) << std::endl;
269 }
270 // TODO add freq validation Stoyan Trilov stoyan.trilov@cern.ch
271 if (print_out)
272 TLOG() << table.str();
273 return table.str();
274}
275//-----------------------------------------------------------------------------
276
277//-----------------------------------------------------------------------------
278std::string
279IONode::get_pll_status(bool print_out) const
280{
281 return get_pll()->get_status(print_out);
282}
283//-----------------------------------------------------------------------------
284
285//-----------------------------------------------------------------------------
286void
288{
289 getNode("csr.ctrl.soft_rst").write(0x1);
290 getClient().dispatch();
291}
292//-----------------------------------------------------------------------------
293
294//-----------------------------------------------------------------------------
295void
297{
299 TLOG_DEBUG(0) << "Soft reset done";
300}
301//-----------------------------------------------------------------------------
302
303//-----------------------------------------------------------------------------
304void
305IONode::reset(const ClockSource& clock_source) const
306{
307 TLOG() << "Setting IO preliminaries: I2C access, etc..";
309
310 // Find the right pll config file
311 std::string clock_config = get_full_clock_config_file_path(clock_source);
312 reset(clock_config);
313}
314//-----------------------------------------------------------------------------
315
316//-----------------------------------------------------------------------------
317std::string
318IONode::get_sfp_status(uint32_t sfp_id, bool print_out) const // NOLINT(build/unsigned)
319{
320 std::stringstream status;
321 std::string sfp_i2c_bus;
322 try {
323 sfp_i2c_bus = m_sfp_i2c_buses.at(sfp_id);
324 } catch (const std::out_of_range& e) {
325 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id), e);
326 }
327 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
328 status << sfp->get_status();
329 if (print_out)
330 TLOG() << status.str();
331 return status.str();
332}
333//-----------------------------------------------------------------------------
334
335//-----------------------------------------------------------------------------
336void
337IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned)
338{
339 std::string sfp_i2c_bus;
340 try {
341 sfp_i2c_bus = m_sfp_i2c_buses.at(sfp_id);
342 } catch (const std::out_of_range& e) {
343 throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id), e);
344 }
345 auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
346 sfp->switch_soft_tx_control_bit(turn_on);
347}
348//-----------------------------------------------------------------------------
349
350} // namespace timing
351} // 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:287
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:337
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:255
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:211
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
virtual void set_up_io_infrastructure() const
Set up i2c buses, enable ICs.
Definition IONode.hpp:174
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
static const std::map< std::string, std::string > & get_clock_config_map()
Definition IONode.hpp:205
virtual std::string get_sfp_status(uint32_t sfp_id, bool print_out=false) const
Print status of on-board SFP.
Definition IONode.cpp:318
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:210
virtual void soft_reset() const
Reset timing node.
Definition IONode.cpp:296
const std::vector< std::string > m_clock_names
Definition IONode.hpp:213
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:230
static const std::map< uint64_t, BoardRevision > & get_board_uid_revision_map()
Definition IONode.hpp:203
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:204
virtual void configure_pll(const std::string &clock_config_file="") const
Configure clock chip.
Definition IONode.cpp:238
static const std::map< BoardRevision, std::string > & get_board_revision_map()
Definition IONode.hpp:202
virtual std::string get_clock_frequencies_table(bool print_out=false) const
Print frequencies of on-board clocks.
Definition IONode.cpp:263
static const std::map< BoardType, std::string > & get_board_type_map()
Definition IONode.hpp:198
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:279
static const std::map< CarrierType, std::string > & get_carrier_type_map()
Definition IONode.hpp:200
static std::string clock_source_to_string(const ClockSource &source)
Definition IONode.hpp:438
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
The DUNE-DAQ namespace.
Definition DataStore.hpp:57
void warning(const Issue &issue)
Definition ers.hpp:115
void error(const Issue &issue)
Definition ers.hpp:81