DUNE-DAQ
DUNE Trigger and Data Acquisition software
Loading...
Searching...
No Matches
dunedaq::timing::MasterNode Class Reference

Class for PD-II/DUNE master timing nodes. More...

#include <MasterNode.hpp>

Inheritance diagram for dunedaq::timing::MasterNode:
[legend]
Collaboration diagram for dunedaq::timing::MasterNode:
[legend]

Public Member Functions

 MasterNode (const uhal::Node &node)
 
virtual ~MasterNode ()
 
std::string get_status (bool print_out=false) const override
 Print the status of the timing node.
 
std::string get_status_with_date (uint32_t clock_frequency_hz, bool print_out=false) const
 Print the status of the timing node.
 
void switch_endpoint_sfp (uint32_t address, bool turn_on) const override
 Control the tx line of endpoint sfp.
 
void enable_upstream_endpoint () const override
 Enable RTT endpoint.
 
void send_fl_cmd (uint32_t command, uint32_t channel, uint32_t number_of_commands=1) const override
 Send a fixed length command.
 
uint32_t measure_endpoint_rtt (uint32_t address, bool control_sfp=true) const override
 Measure the endpoint round trip time.
 
void apply_endpoint_delay (uint32_t address, uint32_t coarse_delay, uint32_t fine_delay, uint32_t phase_delay, bool measure_rtt=false, bool control_sfp=true) const override
 Apply delay to endpoint.
 
void sync_timestamp (TimestampSource source) const override
 Set timestamp to current machine time.
 
uint64_t read_timestamp () const override
 Read the current timestamp word.
 
void set_timestamp (TimestampSource source) const override
 Set the timestamp to current time.
 
void get_info (timingfirmwareinfo::MasterMonitorData &mon_data) const
 Fill the PD-I master monitoring structure.
 
void reset_command_counters () const
 Read some data from endpoint registers.
 
std::vector< uint32_t > transmit_async_packet (const std::vector< uint32_t > &packet, int timeout=500) const
 Send an async packet.
 
void write_endpoint_data (uint16_t endpoint_address, uint8_t reg_address, std::vector< uint8_t > data, bool address_mode) const
 Write some data to endpoint registers.
 
std::vector< uint32_t > read_endpoint_data (uint16_t endpoint_address, uint8_t reg_address, uint8_t data_length, bool address_mode) const
 Read some data from endpoint registers.
 
void disable_timestamp_broadcast () const
 Disable timestamp sending.
 
void enable_timestamp_broadcast () const
 Enable timestamp sending.
 
timingfirmware::EndpointCheckResult scan_endpoint (uint16_t endpoint_address, bool control_sfp) const override
 Scan endpoint.
 
void configure_endpoint_command_decoder (uint16_t endpoint_address, uint8_t slot, uint8_t command) const
 Configure endpoint command decoder.
 
uint32_t get_required_major_firmware_version () const override
 Required major firmware version.
 
uint32_t get_required_minor_firmware_version () const override
 Required minor firmware version.
 
uint32_t get_required_patch_firmware_version () const override
 Required patch firmware version.
 
virtual void apply_endpoint_delay (const ActiveEndpointConfig &ept_config, bool measure_rtt=false) const
 Apply delay to endpoint.
 
- Public Member Functions inherited from dunedaq::timing::MasterNodeInterface
 MasterNodeInterface (const uhal::Node &node)
 
virtual ~MasterNodeInterface ()
 
virtual void enable_periodic_fl_cmd (uint32_t channel, double rate, bool poisson, uint32_t clock_frequency_hz) const
 Configure fake trigger generator.
 
virtual void enable_periodic_fl_cmd (uint32_t command, uint32_t channel, double rate, bool poisson, uint32_t clock_frequency_hz) const
 Configure fake trigger generator.
 
virtual void disable_periodic_fl_cmd (uint32_t channel) const
 Clear fake trigger configuration.
 
- Public Member Functions inherited from dunedaq::timing::TimingNode
 TimingNode (const uhal::Node &node)
 
virtual ~TimingNode ()
 
std::map< std::string, uhal::ValWord< uint32_t > > read_sub_nodes (const uhal::Node &node, bool dispatch=true) const
 Read subnodes.
 
void reset_sub_nodes (const uhal::Node &node, uint32_t aValue=0x0, bool dispatch=true) const
 Reset subnodes.
 

Static Public Attributes

static const uint32_t required_major_firmware_version = 7
 
static const uint32_t required_minor_firmware_version = 5
 
static const uint32_t required_patch_firmware_version = 0
 

Private Member Functions

std::string get_status_tables () const
 Get the status tables.
 

Detailed Description

Class for PD-II/DUNE master timing nodes.

Definition at line 38 of file MasterNode.hpp.

Constructor & Destructor Documentation

◆ MasterNode()

dunedaq::timing::MasterNode::MasterNode ( const uhal::Node & node)
explicit

Definition at line 22 of file MasterNode.cpp.

24{}

◆ ~MasterNode()

dunedaq::timing::MasterNode::~MasterNode ( )
virtual

Definition at line 28 of file MasterNode.cpp.

28{}

Member Function Documentation

◆ apply_endpoint_delay() [1/2]

void dunedaq::timing::MasterNodeInterface::apply_endpoint_delay ( const ActiveEndpointConfig & ept_config,
bool measure_rtt = false ) const
virtual

Apply delay to endpoint.

Reimplemented from dunedaq::timing::MasterNodeInterface.

Definition at line 94 of file MasterNodeInterface.cpp.

29{
30 std::string lEptIdD = ept_config.id;
31 uint32_t ept_address = ept_config.adr; // NOLINT(build/unsigned)
32 uint32_t coarse_Delay = ept_config.cdelay; // NOLINT(build/unsigned)
33 uint32_t fine_delay = ept_config.fdelay; // NOLINT(build/unsigned)
34 uint32_t phase_delay = ept_config.pdelay; // NOLINT(build/unsigned)
35 apply_endpoint_delay(ept_address, coarse_Delay, fine_delay, phase_delay, measure_rtt);
36}
void apply_endpoint_delay(uint32_t address, uint32_t coarse_delay, uint32_t fine_delay, uint32_t phase_delay, bool measure_rtt=false, bool control_sfp=true) const override
Apply delay to endpoint.

◆ apply_endpoint_delay() [2/2]

void dunedaq::timing::MasterNode::apply_endpoint_delay ( uint32_t address,
uint32_t coarse_delay,
uint32_t fine_delay,
uint32_t phase_delay,
bool measure_rtt = false,
bool control_sfp = true ) const
overridevirtual

Apply delay to endpoint.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 205 of file MasterNode.cpp.

211{
212
213 auto global = getNode<MasterGlobalNode>("global");
214 auto echo = getNode<EchoMonitorNode>("echo_mon");
215
216 if (measure_rtt) {
217 if (control_sfp) {
218 // Switch off all TX SFPs
219 // switch_endpoint_sfp(0xffff, false);
220
221 // Turn on the current target
223
224 millisleep(100);
225 }
226
227 try
228 {
229 global.enable_upstream_endpoint();
230 }
231 catch (const timing::ReceiverNotReady& e)
232 {
233 if (control_sfp) {
235 }
236 throw e;
237 }
238
239 uint64_t endpoint_rtt = echo.send_echo_and_measure_delay(); // NOLINT(build/unsigned)
240 TLOG() << "Pre delay adjustment RTT: " << format_reg_value(endpoint_rtt, 10);
241 }
242
243 uint32_t sequence = 0xab;
244 uint32_t address_mode = 1;
245
246 std::vector<uint32_t> tx_packet = { address & 0xff,
247 address >> 8UL,
248 sequence,
249
250 // packet to write coarse delay
251 (0x1 << 7UL) | 0x72, // write transaction on 0x72
252 (address_mode << 7UL) | 0x1, // transaction length of 0x1
253 ((fine_delay & 0xf) << 4UL) | (coarse_delay & 0xf),
254
255 // packet to write fine delay
256 (0x1 << 7UL) | 0x73, // write transaction on 0x73
257 (address_mode << 7UL) | 0x1, // transaction length of 0x1
258 (fine_delay >> 4UL) & 0xff,
259
260 // packet to set skew done
261 (0x1 << 7UL) | 0x70, // write transaction on 0x70
262 (address_mode << 7UL) | 0x1, // transaction length of 0x1
263 0x3, // deskew done
264
265 // packet to resync
266 (0x1 << 7UL) | 0x70, // write transaction on 0x70
267 (address_mode << 7UL) | 0x1, // transaction length of 0x1
268 0x4, // resync
269 };
270
271 tx_packet.back() = tx_packet.back() | (0x1 << 8UL);
272
273 transmit_async_packet(tx_packet, -1);
274
275 if (measure_rtt) {
276 try
277 {
278 global.enable_upstream_endpoint();
279 }
280 catch (const timing::ReceiverNotReady& e)
281 {
282 if (control_sfp)
283 {
285 }
286 throw e;
287 }
288
289 uint64_t endpoint_rtt = echo.send_echo_and_measure_delay(); // NOLINT(build/unsigned)
290 TLOG() << "Post delay adjustment RTT: " << format_reg_value(endpoint_rtt, 10);
291
292 if (control_sfp)
294 }
295}
std::vector< uint32_t > transmit_async_packet(const std::vector< uint32_t > &packet, int timeout=500) const
Send an async packet.
void switch_endpoint_sfp(uint32_t address, bool turn_on) const override
Control the tx line of endpoint sfp.
#define TLOG(...)
Definition macro.hpp:22
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

◆ configure_endpoint_command_decoder()

void dunedaq::timing::MasterNode::configure_endpoint_command_decoder ( uint16_t endpoint_address,
uint8_t slot,
uint8_t command ) const

Configure endpoint command decoder.

Definition at line 593 of file MasterNode.cpp.

594{
595 write_endpoint_data(endpoint_address, 0x60+slot, {command}, true);
596}
void write_endpoint_data(uint16_t endpoint_address, uint8_t reg_address, std::vector< uint8_t > data, bool address_mode) const
Write some data to endpoint registers.

◆ disable_timestamp_broadcast()

void dunedaq::timing::MasterNode::disable_timestamp_broadcast ( ) const

Disable timestamp sending.

Definition at line 503 of file MasterNode.cpp.

504{
505 getNode("global.csr.ctrl.ts_en").write(0x0);
506 getClient().dispatch();
507}

◆ enable_timestamp_broadcast()

void dunedaq::timing::MasterNode::enable_timestamp_broadcast ( ) const

Enable timestamp sending.

Definition at line 511 of file MasterNode.cpp.

512{
513 getNode("global.csr.ctrl.ts_en").write(0x1);
514 getClient().dispatch();
515}

◆ enable_upstream_endpoint()

void dunedaq::timing::MasterNode::enable_upstream_endpoint ( ) const
overridevirtual

Enable RTT endpoint.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 130 of file MasterNode.cpp.

131{
132 auto global = getNode<MasterGlobalNode>("global");
133 global.enable_upstream_endpoint();
134}

◆ get_info()

void dunedaq::timing::MasterNode::get_info ( timingfirmwareinfo::MasterMonitorData & mon_data) const
virtual

Fill the PD-I master monitoring structure.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 327 of file MasterNode.cpp.

328{
329 mon_data.timestamp = read_timestamp();
330
331 auto control = read_sub_nodes(getNode("global.csr.ctrl"), false);
332 auto state = read_sub_nodes(getNode("global.csr.stat"), false);
333 getClient().dispatch();
334
335 mon_data.ts_bcast_enable = control.at("ts_en").value();
336 mon_data.ts_valid = state.at("ts_valid").value();
337 mon_data.ts_tx_err = state.at("ts_tx_err").value();
338 mon_data.tx_err = state.at("tx_err").value();
339 mon_data.ctrs_rdy = state.at("ctrs_rdy").value();
340
341// ic.add(mon_data);
342
343// uint number_of_commands = 0xff;
344
345// getNode("cmd_ctrs.addr").write(0x0);
346// auto counters = getNode("cmd_ctrs.data").readBlock(number_of_commands);
347// getClient().dispatch();
348
349// for (uint i = 0; i < number_of_commands; ++i) { // NOLINT(build/unsigned)
350
351// timingfirmwareinfo::SentCommandCounter cmd_counter;
352// opmonlib::InfoCollector cmd_counter_ic;
353
354// cmd_counter.counts = counters.at(i);
355
356// std::stringstream channel;
357// channel << "cmd_0x" << std::hex << i;
358
359// cmd_counter_ic.add(cmd_counter);
360// ic.add(channel.str(), cmd_counter_ic);
361// }
362
363// getNode<FLCmdGeneratorNode>("scmd_gen").get_info(ic, level);
364}
uint64_t read_timestamp() const override
Read the current timestamp word.
std::map< std::string, uhal::ValWord< uint32_t > > read_sub_nodes(const uhal::Node &node, bool dispatch=true) const
Read subnodes.
The opmon infrastructure has not been set up in the The control service has been defined multiple times for the application app_name you need to define only one service called control
Definition util.hpp:40

◆ get_required_major_firmware_version()

uint32_t dunedaq::timing::MasterNode::get_required_major_firmware_version ( ) const
inlineoverridevirtual

Required major firmware version.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 156 of file MasterNode.hpp.

static const uint32_t required_major_firmware_version

◆ get_required_minor_firmware_version()

uint32_t dunedaq::timing::MasterNode::get_required_minor_firmware_version ( ) const
inlineoverridevirtual

Required minor firmware version.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 161 of file MasterNode.hpp.

static const uint32_t required_minor_firmware_version

◆ get_required_patch_firmware_version()

uint32_t dunedaq::timing::MasterNode::get_required_patch_firmware_version ( ) const
inlineoverridevirtual

Required patch firmware version.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 166 of file MasterNode.hpp.

static const uint32_t required_patch_firmware_version

◆ get_status()

std::string dunedaq::timing::MasterNode::get_status ( bool print_out = false) const
overridevirtual

Print the status of the timing node.

Implements dunedaq::timing::TimingNode.

Definition at line 77 of file MasterNode.cpp.

78{
79 std::stringstream status;
80 auto raw_timestamp = getNode<TimestampGeneratorNode>("tstamp").read_raw_timestamp();
81 status << "Timestamp: 0x" << std::hex << tstamp2int(raw_timestamp) << std::endl << std::endl;
83
84 if (print_out)
85 TLOG() << status.str();
86 return status.str();
87}
std::string get_status_tables() const
Get the status tables.
uint64_t tstamp2int(uhal::ValVector< uint32_t > raw_timestamp)
Definition toolbox.cpp:175

◆ get_status_tables()

std::string dunedaq::timing::MasterNode::get_status_tables ( ) const
private

Get the status tables.

Definition at line 33 of file MasterNode.cpp.

34{
35 std::stringstream status;
36
37 status << getNode<TimestampGeneratorNode>("tstamp").get_status();
38 status << std::endl;
39
40 status << getNode<MasterGlobalNode>("global").get_status();
41 status << std::endl;
42
43 status << getNode<FLCmdGeneratorNode>("scmd_gen").get_cmd_counters_table();
44 status << std::endl;
45
46 getNode("cmd_ctrs.addr").write(0x0);
47 auto counters = getNode("cmd_ctrs.data").readBlock(0xff);
48 getClient().dispatch();
49
50 std::vector<uint32_t> non_zero_counters;
51 std::vector<std::string> counter_labels;
52
53 for (uint i=0; i < counters.size(); ++i)
54 {
55 auto counter = counters.at(i);
56 if (counter > 0)
57 {
58 counter_labels.push_back(format_reg_value(i));
59 non_zero_counters.push_back(counter);
60 }
61 }
62
63 std::vector<std::vector<uint32_t>> counters_container = { non_zero_counters }; // NOLINT(build/unsigned)
64
65 status << format_counters_table(counters_container, { "Sent cmd counters" }, "Master cmd counters (>0)", counter_labels);
66 status << std::endl;
67
68 auto acmd_buf = read_sub_nodes(getNode("acmd_buf.stat"));
69 status << format_reg_table(acmd_buf, "Master acmd buffer");
70
71 return status.str();
72}
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_counters_table(std::vector< T > counter_nodes, std::vector< std::string > counter_node_titles, std::string table_title, std::vector< std::string > counter_labels, std::string counter_labels_header)
Format reg-value table.
Definition toolbox.hxx:216

◆ get_status_with_date()

std::string dunedaq::timing::MasterNode::get_status_with_date ( uint32_t clock_frequency_hz,
bool print_out = false ) const

Print the status of the timing node.

Definition at line 92 of file MasterNode.cpp.

93{
94 std::stringstream status;
95 auto raw_timestamp = getNode<TimestampGeneratorNode>("tstamp").read_raw_timestamp();
96 status << "Timestamp: 0x" << std::hex << tstamp2int(raw_timestamp) << " -> " << format_timestamp(raw_timestamp, clock_frequency_hz) << std::endl
97 << std::endl;
99
100 if (print_out)
101 TLOG() << status.str();
102 return status.str();
103}
std::string format_timestamp(uhal::ValVector< uint32_t > raw_timestamp, uint32_t clock_frequency_hz)
Definition toolbox.cpp:233

◆ measure_endpoint_rtt()

uint32_t dunedaq::timing::MasterNode::measure_endpoint_rtt ( uint32_t address,
bool control_sfp = true ) const
overridevirtual

Measure the endpoint round trip time.

Returns
{ description_of_the_return_value }

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 165 of file MasterNode.cpp.

166{
167
168 auto global = getNode<MasterGlobalNode>("global");
169 auto echo = getNode<EchoMonitorNode>("echo_mon");
170
171 if (control_sfp)
172 {
173 // Switch off all TX SFPs
174 //switch_endpoint_sfp(0xffff, false);
175
176 // Turn on the current target
178
179 millisleep(100);
180
181 try
182 {
183 global.enable_upstream_endpoint();
184 }
185 catch (const timing::ReceiverNotReady& e)
186 {
187 if (control_sfp) {
189 }
190 throw e;
191 }
192 }
193
194 uint32_t endpoint_rtt = echo.send_echo_and_measure_delay(); // NOLINT(build/unsigned)
195
196 if (control_sfp)
198
199 return endpoint_rtt;
200}

◆ read_endpoint_data()

std::vector< uint32_t > dunedaq::timing::MasterNode::read_endpoint_data ( uint16_t endpoint_address,
uint8_t reg_address,
uint8_t data_length,
bool address_mode ) const

Read some data from endpoint registers.

Definition at line 472 of file MasterNode.cpp.

473{
474 if (data_length > 0x3f || data_length == 0)
475 {
476 TLOG() << "invalid data length";
477 // TODO throw something
478 }
479
480 // TODO make sequence a function argument?
481 uint32_t sequence = 0xab;
482 std::vector<uint32_t> tx_packet = { static_cast<uint32_t>(endpoint_address & 0xff),
483 static_cast<uint32_t>(endpoint_address >> 8UL),
484 sequence,
485 // bit 7 = 0 -> read
486 reg_address,
487 static_cast<uint32_t>((0x1 << 8UL) | (address_mode << 7UL) | (0x3f & data_length))
488 };
489
490 auto result = transmit_async_packet(tx_packet);
491
492 // get parts we actually want
493 std::vector<uint32_t> result_data (result.begin()+3, result.begin()+3+data_length);
494
495 // strip off the bit 8 which is high for last byte
496 result_data.back() = result_data.back() & 0xff;
497
498 return result_data;
499}

◆ read_timestamp()

uint64_t dunedaq::timing::MasterNode::read_timestamp ( ) const
overridevirtual

Read the current timestamp word.

Returns
{ description_of_the_return_value }

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 311 of file MasterNode.cpp.

312{
313 return getNode<TimestampGeneratorNode>("tstamp").read_timestamp();
314}

◆ reset_command_counters()

void dunedaq::timing::MasterNode::reset_command_counters ( ) const

Read some data from endpoint registers.

Definition at line 368 of file MasterNode.cpp.

369{
370 auto global = getNode<MasterGlobalNode>("global");
371 global.reset_command_counters();
372}

◆ scan_endpoint()

timingfirmware::EndpointCheckResult dunedaq::timing::MasterNode::scan_endpoint ( uint16_t endpoint_address,
bool control_sfp ) const
overridevirtual

Scan endpoint.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 520 of file MasterNode.cpp.

521{
522 timingfirmware::EndpointCheckResult result;
523 auto global = getNode<MasterGlobalNode>("global");
524 auto echo = getNode<EchoMonitorNode>("echo_mon");
525
526 timingfirmware::EndpointCheckResult endpoint_result;
527 endpoint_result.address = endpoint_address;
528
529 // is endpoint sfp switched on?
530 // are any relevant muxes set to correct channel?
531 if (control_sfp)
532 {
533 switch_endpoint_sfp(endpoint_address, true);
534
535 millisleep(100);
536 }
537
538 try
539 {
540 global.enable_upstream_endpoint();
541 }
542 catch (const timing::ReceiverNotReady& e)
543 {
544 switch_endpoint_sfp(endpoint_address, false);
545
546 //ers::error(MonitoredEndpointDead(ERS_HERE, endpoint_address));
547
548 return endpoint_result;
549 }
550
551 endpoint_result.alive = true;
552 endpoint_result.round_trip_time = echo.send_echo_and_measure_delay();
553 TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << " alive. RTT: " << endpoint_result.round_trip_time;
554
555 auto ept_state = read_endpoint_data(endpoint_address, 0x71, 0x1, 0x1).at(0) & 0xf;
556 TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << " state: 0x" << std::hex << ept_state;
557 endpoint_result.state = ept_state;
558
559 if (ept_state == 0x6)
560 {
561 TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", applying delays of: " << 0x0;
562 ers::info(MonitoredEndpointDelaySet(ERS_HERE, 0x0, endpoint_address, ept_state));
563 apply_endpoint_delay(endpoint_address, 0x0, 0x0, 0x0, false, false);
564
565 endpoint_result.applied_delay = 0x0;
566
567 auto ept_state_after_delays = read_endpoint_data(endpoint_address, 0x71, 0x1, 0x1).at(0) & 0xf;
568 TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", state after delays apply: " << ept_state_after_delays;
569 endpoint_result.state_after_delay_apply = ept_state_after_delays;
570
571 endpoint_result.round_trip_time_after_delay_apply = echo.send_echo_and_measure_delay();
572 TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", RTT after delays apply: " << endpoint_result.round_trip_time_after_delay_apply;
573 }
574 else if (ept_state == 0x7 || ept_state == 0x8)
575 {
576 TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", delays not needed";
577 }
578 else
579 {
580 ers::error(MonitoredEndpointUnexpectedState(ERS_HERE, endpoint_address, ept_state));
581 }
582
583 if (control_sfp)
584 {
585 switch_endpoint_sfp(endpoint_address, false);
586 }
587
588 return endpoint_result;
589}
#define ERS_HERE
std::vector< uint32_t > read_endpoint_data(uint16_t endpoint_address, uint8_t reg_address, uint8_t data_length, bool address_mode) const
Read some data from endpoint registers.
#define TLOG_DEBUG(lvl,...)
Definition Logging.hpp:112
void info(const Issue &issue)
Definition ers.hpp:95
void error(const Issue &issue)
Definition ers.hpp:81

◆ send_fl_cmd()

void dunedaq::timing::MasterNode::send_fl_cmd ( uint32_t command,
uint32_t channel,
uint32_t number_of_commands = 1 ) const
overridevirtual

Send a fixed length command.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 139 of file MasterNode.cpp.

142{
143 for (uint32_t i = 0; i < number_of_commands; i++) { // NOLINT(build/unsigned)
144 getNode<FLCmdGeneratorNode>("scmd_gen").send_fl_cmd(command, channel);
145
146 auto ts_l = getNode("cmd_log.tstamp_l").read();
147 auto ts_h = getNode("cmd_log.tstamp_h").read();
148 auto sent_cmd = getNode("cmd_log.cmd").read();
149 getClient().dispatch();
150
151 if (sent_cmd.value() != command)
152 {
153 TLOG() << "cmd in sent log: 0x" << std::hex << command << ", does not match requested 0x: " << sent_cmd.value();
154 // TODO throw something
155 }
156 uint64_t timestamp = (uint64_t)ts_h.value() << 32 | ts_l.value();
157 TLOG() << "Command sent " << "(" << format_reg_value(command) << ") from generator "
158 << format_reg_value(channel) << " @time " << std::hex << std::showbase << timestamp;
159 }
160}

◆ set_timestamp()

void dunedaq::timing::MasterNode::set_timestamp ( TimestampSource source) const
overridevirtual

Set the timestamp to current time.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 319 of file MasterNode.cpp.

320{
321 getNode<TimestampGeneratorNode>("tstamp").set_timestamp(source);
322}

◆ switch_endpoint_sfp()

void dunedaq::timing::MasterNode::switch_endpoint_sfp ( uint32_t address,
bool turn_on ) const
overridevirtual

Control the tx line of endpoint sfp.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 108 of file MasterNode.cpp.

109{
110 uint32_t sequence = 0xab;
111 uint32_t address_mode = 1;
112
113 std::vector<uint32_t> tx_packet = { address & 0xff,
114 address >> 8UL,
115 sequence,
116
117 // packet to reset rx
118 (0x1 << 7UL) | 0x70, // write transaction on 0x70
119 (address_mode << 7UL) | 0x1, // transaction length of 0x1
120 turn_on,
121 };
122 tx_packet.back() = tx_packet.back() | (0x1 << 8UL);
123
124 auto result = transmit_async_packet(tx_packet, -1);
125}

◆ sync_timestamp()

void dunedaq::timing::MasterNode::sync_timestamp ( TimestampSource source) const
overridevirtual

Set timestamp to current machine time.

Implements dunedaq::timing::MasterNodeInterface.

Definition at line 300 of file MasterNode.cpp.

301{
302 set_timestamp(source);
303
305 TLOG() << "Timestamp broadcast enabled";
306}
void set_timestamp(TimestampSource source) const override
Set the timestamp to current time.
void enable_timestamp_broadcast() const
Enable timestamp sending.

◆ transmit_async_packet()

std::vector< uint32_t > dunedaq::timing::MasterNode::transmit_async_packet ( const std::vector< uint32_t > & packet,
int timeout = 500 ) const

Send an async packet.

Definition at line 377 of file MasterNode.cpp.

378{
379 // TODO: check for valid packet
380
381 reset_sub_nodes(getNode("acmd_buf.txbuf"));
382
383 TLOG_DEBUG(11) << "tx packet: ";
384 for (auto t : packet)
385 TLOG_DEBUG(11) << std::hex << "0x" << t;
386
387 getNode("acmd_buf.txbuf").writeBlock(packet);
388 getClient().dispatch();
389
390 // we do not expect a reply
391 if (timeout < 0)
392 {
393 std::vector<uint32_t> empty_vector;
394 return empty_vector;
395 }
396
397 uhal::ValWord<uint32_t> buffer_ready; // NOLINT(build/unsigned)
398 uhal::ValWord<uint32_t> buffer_timeout; // NOLINT(build/unsigned)
399
400 // start time counting
401 auto start = std::chrono::high_resolution_clock::now();
402
403 // Wait for the buffer to be happy
404 while (true) {
405
406 buffer_ready = getNode("acmd_buf.stat.ready").read();
407 buffer_timeout = getNode("acmd_buf.stat.timeout").read();
408 getClient().dispatch();
409
410 TLOG_DEBUG(10) << "async buffer ready: 0x" << buffer_ready.value() << ", timeout: " << buffer_timeout.value();
411
412 if (buffer_timeout)
413 throw VLCommandReplyTimeout(ERS_HERE);
414
415 if (buffer_ready)
416 break;
417
418 auto now = std::chrono::high_resolution_clock::now();
419 auto us_since_start = std::chrono::duration_cast<std::chrono::microseconds>(now - start);
420
421 if (us_since_start.count() > timeout)
422 throw VLCommandReplyBufferFlagTimeout(ERS_HERE, timeout);
423
424 std::this_thread::sleep_for(std::chrono::microseconds(50));
425 }
426
427 auto rx_packet = getNode("acmd_buf.rxbuf").readBlock(0x20);
428 getClient().dispatch();
429
430 if (rx_packet.at(0) != 0xff || rx_packet.at(1) != 0xff || rx_packet.at(2) != packet.at(2))
431 {
432 ers::warning(InvalidVLCommandReplyPacket(ERS_HERE, rx_packet.at(0), rx_packet.at(1), rx_packet.at(2)));
433 }
434
435 TLOG_DEBUG(11) << "async result: ";
436 for (auto r : rx_packet)
437 TLOG_DEBUG(11) << std::hex << "0x" << r;
438
439 return rx_packet.value();
440}
void reset_sub_nodes(const uhal::Node &node, uint32_t aValue=0x0, bool dispatch=true) const
Reset subnodes.
static int64_t now()
void warning(const Issue &issue)
Definition ers.hpp:115

◆ write_endpoint_data()

void dunedaq::timing::MasterNode::write_endpoint_data ( uint16_t endpoint_address,
uint8_t reg_address,
std::vector< uint8_t > data,
bool address_mode ) const

Write some data to endpoint registers.

Definition at line 445 of file MasterNode.cpp.

446{
447 auto data_length = data.size();
448 if (data_length > 0x3f || data_length == 0)
449 {
450 TLOG() << "invalid data length";
451 }
452
453 // TODO make sequence a function argument?
454 uint32_t sequence = 0xab;
455
456 std::vector<uint32_t> tx_packet = { static_cast<uint32_t>(endpoint_address & 0xff),
457 static_cast<uint32_t>(endpoint_address >> 8UL),
458 sequence,
459 // bit 7 = 1 -> write
460 static_cast<uint32_t>((0x1 << 7UL) | reg_address),
461 static_cast<uint32_t>((address_mode << 7UL) | (0x3f & data_length))
462 };
463 tx_packet.insert(tx_packet.end(), data.begin(), data.end());
464 tx_packet.back() = tx_packet.back() | (0x1 << 8UL);
465
466 auto result = transmit_async_packet(tx_packet);
467}

Member Data Documentation

◆ required_major_firmware_version

const uint32_t dunedaq::timing::MasterNode::required_major_firmware_version = 7
static

Definition at line 168 of file MasterNode.hpp.

◆ required_minor_firmware_version

const uint32_t dunedaq::timing::MasterNode::required_minor_firmware_version = 5
static

Definition at line 169 of file MasterNode.hpp.

◆ required_patch_firmware_version

const uint32_t dunedaq::timing::MasterNode::required_patch_firmware_version = 0
static

Definition at line 170 of file MasterNode.hpp.


The documentation for this class was generated from the following files: