LCOV - code coverage report
Current view: top level - timing/src - MasterNode.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 271 0
Test Date: 2025-12-21 13:07:08 Functions: 0.0 % 43 0

            Line data    Source code
       1              : /**
       2              :  * @file MasterNode.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/MasterNode.hpp"
      10              : #include "timing/MasterGlobalNode.hpp"
      11              : 
      12              : #include "logging/Logging.hpp"
      13              : 
      14              : #include <string>
      15              : 
      16              : namespace dunedaq {
      17              : namespace timing {
      18              : 
      19            0 : UHAL_REGISTER_DERIVED_NODE(MasterNode)
      20              : 
      21              : //-----------------------------------------------------------------------------
      22            0 : MasterNode::MasterNode(const uhal::Node& node)
      23            0 :   : MasterNodeInterface(node)
      24            0 : {}
      25              : //-----------------------------------------------------------------------------
      26              : 
      27              : //-----------------------------------------------------------------------------
      28            0 : MasterNode::~MasterNode() {}
      29              : //-----------------------------------------------------------------------------
      30              : 
      31              : //-----------------------------------------------------------------------------
      32              : std::string
      33            0 : MasterNode::get_status_tables() const
      34              : {
      35            0 :   std::stringstream status;
      36              : 
      37            0 :   status << getNode<TimestampGeneratorNode>("tstamp").get_status();
      38            0 :   status << std::endl;
      39              : 
      40            0 :   status << getNode<MasterGlobalNode>("global").get_status();
      41            0 :   status << std::endl;
      42              : 
      43            0 :   status << getNode<FLCmdGeneratorNode>("scmd_gen").get_cmd_counters_table();
      44            0 :   status << std::endl;
      45              : 
      46            0 :   getNode("cmd_ctrs.addr").write(0x0);
      47            0 :   auto counters = getNode("cmd_ctrs.data").readBlock(0xff);
      48            0 :   getClient().dispatch();
      49              : 
      50            0 :   std::vector<uint32_t> non_zero_counters;
      51            0 :   std::vector<std::string> counter_labels;
      52              : 
      53            0 :   for (uint i=0; i < counters.size(); ++i) 
      54              :   {
      55            0 :     auto counter = counters.at(i);
      56            0 :     if (counter > 0)
      57              :     {
      58            0 :       counter_labels.push_back(format_reg_value(i));
      59            0 :       non_zero_counters.push_back(counter);
      60              :     }
      61              :   }
      62              : 
      63            0 :   std::vector<std::vector<uint32_t>> counters_container = { non_zero_counters }; // NOLINT(build/unsigned)
      64              : 
      65            0 :   status << format_counters_table(counters_container, { "Sent cmd counters" }, "Master cmd counters (>0)", counter_labels);
      66            0 :   status << std::endl;
      67              : 
      68            0 :   auto acmd_buf = read_sub_nodes(getNode("acmd_buf.stat"));
      69            0 :   status << format_reg_table(acmd_buf, "Master acmd buffer");
      70              : 
      71            0 :   return status.str();
      72            0 : }
      73              : //-----------------------------------------------------------------------------
      74              : 
      75              : //-----------------------------------------------------------------------------
      76              : std::string
      77            0 : MasterNode::get_status(bool print_out) const
      78              : {
      79            0 :   std::stringstream status;
      80            0 :   auto raw_timestamp = getNode<TimestampGeneratorNode>("tstamp").read_raw_timestamp();
      81            0 :   status << "Timestamp: 0x" << std::hex << tstamp2int(raw_timestamp) << std::endl << std::endl;
      82            0 :   status << get_status_tables();
      83              : 
      84            0 :   if (print_out)
      85            0 :     TLOG() << status.str();
      86            0 :   return status.str();
      87            0 : }
      88              : //-----------------------------------------------------------------------------
      89              : 
      90              : //-----------------------------------------------------------------------------
      91              : std::string
      92            0 : MasterNode::get_status_with_date(uint32_t clock_frequency_hz, bool print_out) const // NOLINT(build/unsigned)
      93              : {
      94            0 :   std::stringstream status;
      95            0 :   auto raw_timestamp = getNode<TimestampGeneratorNode>("tstamp").read_raw_timestamp();
      96            0 :   status << "Timestamp: 0x" << std::hex << tstamp2int(raw_timestamp) << " -> " << format_timestamp(raw_timestamp, clock_frequency_hz) << std::endl
      97            0 :           << std::endl;
      98            0 :   status << get_status_tables();
      99              : 
     100            0 :   if (print_out)
     101            0 :     TLOG() << status.str();
     102            0 :   return status.str();
     103            0 : }
     104              : //-----------------------------------------------------------------------------
     105              : 
     106              : //-----------------------------------------------------------------------------
     107              : void
     108            0 : MasterNode::switch_endpoint_sfp(uint32_t address, bool turn_on) const // NOLINT(build/unsigned)
     109              : {
     110            0 :     uint32_t sequence = 0xab;
     111            0 :     uint32_t address_mode = 1;
     112              :     
     113            0 :     std::vector<uint32_t> tx_packet = { address & 0xff, 
     114            0 :                                         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            0 :                                         turn_on,
     121            0 :                                       };
     122            0 :   tx_packet.back() = tx_packet.back() | (0x1 << 8UL);
     123              : 
     124            0 :   auto result = transmit_async_packet(tx_packet, -1);
     125            0 : }
     126              : //-----------------------------------------------------------------------------
     127              : 
     128              : //-----------------------------------------------------------------------------
     129              : void
     130            0 : MasterNode::enable_upstream_endpoint() const
     131              : {
     132            0 :   auto global = getNode<MasterGlobalNode>("global");
     133            0 :   global.enable_upstream_endpoint();
     134            0 : }
     135              : //-----------------------------------------------------------------------------
     136              : 
     137              : //-----------------------------------------------------------------------------
     138              : void
     139            0 : MasterNode::send_fl_cmd(uint32_t command,
     140              :                         uint32_t channel,                  // NOLINT(build/unsigned)
     141              :                         uint32_t number_of_commands) const // NOLINT(build/unsigned)
     142              : {
     143            0 :   for (uint32_t i = 0; i < number_of_commands; i++) { // NOLINT(build/unsigned)
     144            0 :     getNode<FLCmdGeneratorNode>("scmd_gen").send_fl_cmd(command, channel);
     145              :     
     146            0 :     auto ts_l = getNode("cmd_log.tstamp_l").read();
     147            0 :     auto ts_h = getNode("cmd_log.tstamp_h").read();
     148            0 :     auto sent_cmd = getNode("cmd_log.cmd").read();
     149            0 :     getClient().dispatch();
     150              : 
     151            0 :     if (sent_cmd.value() != command)
     152              :     {
     153            0 :       TLOG() << "cmd in sent log: 0x" << std::hex << command << ", does not match requested 0x: " << sent_cmd.value();
     154              :       // TODO throw something
     155              :     }
     156            0 :     uint64_t timestamp = (uint64_t)ts_h.value() << 32 | ts_l.value();
     157            0 :     TLOG() << "Command sent " << "(" << format_reg_value(command) << ") from generator "
     158            0 :          << format_reg_value(channel) << " @time " << std::hex << std::showbase << timestamp;
     159            0 :   }
     160            0 : }
     161              : //-----------------------------------------------------------------------------
     162              : 
     163              : //-----------------------------------------------------------------------------
     164              : uint32_t                                                                      // NOLINT(build/unsigned)
     165            0 : MasterNode::measure_endpoint_rtt(uint32_t address, bool control_sfp) const // NOLINT(build/unsigned)
     166              : {
     167              : 
     168            0 :   auto global = getNode<MasterGlobalNode>("global");
     169            0 :   auto echo = getNode<EchoMonitorNode>("echo_mon");
     170              : 
     171            0 :   if (control_sfp)
     172              :   {
     173              :     // Switch off all TX SFPs
     174              :     //switch_endpoint_sfp(0xffff, false);
     175              : 
     176              :     // Turn on the current target
     177            0 :     switch_endpoint_sfp(address, true);
     178              : 
     179            0 :     millisleep(100);
     180              : 
     181            0 :     try
     182              :     {
     183            0 :       global.enable_upstream_endpoint();
     184              :     }
     185            0 :     catch (const timing::ReceiverNotReady& e)
     186              :     {
     187            0 :       if (control_sfp) {
     188            0 :         switch_endpoint_sfp(address, false);
     189              :       }
     190            0 :       throw e;
     191            0 :     }
     192              :   }
     193              : 
     194            0 :   uint32_t endpoint_rtt = echo.send_echo_and_measure_delay(); // NOLINT(build/unsigned)
     195              : 
     196            0 :   if (control_sfp)
     197            0 :     switch_endpoint_sfp(address, false);
     198              : 
     199            0 :   return endpoint_rtt;
     200            0 : }
     201              : //-----------------------------------------------------------------------------
     202              : 
     203              : //-----------------------------------------------------------------------------
     204              : void
     205            0 : MasterNode::apply_endpoint_delay(uint32_t address,      // NOLINT(build/unsigned)
     206              :                                     uint32_t coarse_delay, // NOLINT(build/unsigned)
     207              :                                     uint32_t fine_delay,   // NOLINT(build/unsigned)
     208              :                                     uint32_t /*phase_delay*/,  // NOLINT(build/unsigned)
     209              :                                     bool measure_rtt,
     210              :                                     bool control_sfp) const
     211              : {
     212              : 
     213            0 :   auto global = getNode<MasterGlobalNode>("global");
     214            0 :   auto echo = getNode<EchoMonitorNode>("echo_mon");
     215              : 
     216            0 :   if (measure_rtt) {
     217            0 :     if (control_sfp) {
     218              :       // Switch off all TX SFPs
     219              :       // switch_endpoint_sfp(0xffff, false);
     220              : 
     221              :       // Turn on the current target
     222            0 :       switch_endpoint_sfp(address, true);
     223              : 
     224            0 :       millisleep(100);
     225              :     }
     226              : 
     227            0 :     try
     228              :     {
     229            0 :       global.enable_upstream_endpoint();
     230              :     }
     231            0 :     catch (const timing::ReceiverNotReady& e)
     232              :     {
     233            0 :       if (control_sfp) {
     234            0 :         switch_endpoint_sfp(address, false);
     235              :       }
     236            0 :       throw e;
     237            0 :     }
     238              : 
     239            0 :     uint64_t endpoint_rtt = echo.send_echo_and_measure_delay(); // NOLINT(build/unsigned)
     240            0 :     TLOG() << "Pre delay adjustment RTT:  " << format_reg_value(endpoint_rtt, 10);
     241              :   }
     242              : 
     243            0 :   uint32_t sequence = 0xab;
     244            0 :   uint32_t address_mode = 1;
     245              :     
     246            0 :   std::vector<uint32_t> tx_packet = { address & 0xff, 
     247            0 :                                         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            0 :                                         ((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            0 :                                         (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            0 :                                     };
     270              : 
     271            0 :   tx_packet.back() = tx_packet.back() | (0x1 << 8UL);
     272              : 
     273            0 :   transmit_async_packet(tx_packet, -1);
     274              : 
     275            0 :   if (measure_rtt) {
     276            0 :     try
     277              :     {
     278            0 :       global.enable_upstream_endpoint();
     279              :     }
     280            0 :     catch (const timing::ReceiverNotReady& e)
     281              :     {
     282            0 :       if (control_sfp)
     283              :       {
     284            0 :         switch_endpoint_sfp(address, false);
     285              :       }
     286            0 :       throw e;
     287            0 :     }
     288              : 
     289            0 :     uint64_t endpoint_rtt = echo.send_echo_and_measure_delay(); // NOLINT(build/unsigned)
     290            0 :     TLOG() << "Post delay adjustment RTT: " << format_reg_value(endpoint_rtt, 10);
     291              : 
     292            0 :     if (control_sfp)
     293            0 :       switch_endpoint_sfp(address, false);
     294              :   }
     295            0 : }
     296              : //-----------------------------------------------------------------------------
     297              : 
     298              : //-----------------------------------------------------------------------------
     299              : void
     300            0 : MasterNode::sync_timestamp(TimestampSource source) const // NOLINT(build/unsigned)
     301              : {
     302            0 :   set_timestamp(source);
     303              : 
     304            0 :   enable_timestamp_broadcast();
     305            0 :   TLOG() << "Timestamp broadcast enabled";
     306            0 : }
     307              : //-----------------------------------------------------------------------------
     308              : 
     309              : //-----------------------------------------------------------------------------
     310              : uint64_t // NOLINT(build/unsigned)
     311            0 : MasterNode::read_timestamp() const
     312              : {
     313            0 :   return getNode<TimestampGeneratorNode>("tstamp").read_timestamp();
     314              : }
     315              : //-----------------------------------------------------------------------------
     316              : 
     317              : //-----------------------------------------------------------------------------
     318              : void
     319            0 : MasterNode::set_timestamp(TimestampSource source) const // NOLINT(build/unsigned)
     320              : {
     321            0 :   getNode<TimestampGeneratorNode>("tstamp").set_timestamp(source);
     322            0 : }
     323              : //-----------------------------------------------------------------------------
     324              : 
     325              : //-----------------------------------------------------------------------------
     326              : void
     327            0 : MasterNode::get_info(timingfirmwareinfo::MasterMonitorData& mon_data) const
     328              : {
     329            0 :   mon_data.timestamp = read_timestamp();
     330              : 
     331            0 :   auto control = read_sub_nodes(getNode("global.csr.ctrl"), false);
     332            0 :   auto state = read_sub_nodes(getNode("global.csr.stat"), false);
     333            0 :   getClient().dispatch();
     334              : 
     335            0 :   mon_data.ts_bcast_enable = control.at("ts_en").value();
     336            0 :   mon_data.ts_valid = state.at("ts_valid").value();
     337            0 :   mon_data.ts_tx_err = state.at("ts_tx_err").value();
     338            0 :   mon_data.tx_err = state.at("tx_err").value();
     339            0 :   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            0 : }
     365              : //-----------------------------------------------------------------------------
     366              : 
     367              : //-----------------------------------------------------------------------------
     368            0 : void MasterNode::reset_command_counters() const
     369              : {
     370            0 :   auto global = getNode<MasterGlobalNode>("global");
     371            0 :   global.reset_command_counters();
     372            0 : }
     373              : //-----------------------------------------------------------------------------
     374              : 
     375              : //-----------------------------------------------------------------------------
     376              : std::vector<uint32_t>
     377            0 : MasterNode::transmit_async_packet(const std::vector<uint32_t>& packet, int timeout) const
     378              : {
     379              :   // TODO: check for valid packet
     380              : 
     381            0 :   reset_sub_nodes(getNode("acmd_buf.txbuf"));
     382              : 
     383            0 :   TLOG_DEBUG(11) << "tx packet: ";
     384            0 :   for (auto t : packet)
     385            0 :     TLOG_DEBUG(11) << std::hex << "0x" << t;
     386              : 
     387            0 :   getNode("acmd_buf.txbuf").writeBlock(packet);
     388            0 :   getClient().dispatch();
     389              : 
     390              :   // we do not expect a reply
     391            0 :   if (timeout < 0)
     392              :   {
     393            0 :     std::vector<uint32_t> empty_vector;
     394            0 :     return empty_vector;
     395            0 :   }
     396              : 
     397            0 :   uhal::ValWord<uint32_t> buffer_ready;  // NOLINT(build/unsigned)
     398            0 :   uhal::ValWord<uint32_t> buffer_timeout;  // NOLINT(build/unsigned)
     399              : 
     400              :   // start time counting
     401            0 :   auto start = std::chrono::high_resolution_clock::now();
     402              : 
     403              :   // Wait for the buffer to be happy
     404            0 :   while (true) {
     405              : 
     406            0 :     buffer_ready = getNode("acmd_buf.stat.ready").read();
     407            0 :     buffer_timeout = getNode("acmd_buf.stat.timeout").read();
     408            0 :     getClient().dispatch();
     409              :     
     410            0 :     TLOG_DEBUG(10) << "async buffer ready: 0x" << buffer_ready.value() << ", timeout: " << buffer_timeout.value();
     411              :   
     412            0 :     if (buffer_timeout)
     413            0 :       throw VLCommandReplyTimeout(ERS_HERE);
     414              :      
     415            0 :     if (buffer_ready)
     416              :       break;
     417              : 
     418            0 :     auto now = std::chrono::high_resolution_clock::now();
     419            0 :     auto us_since_start = std::chrono::duration_cast<std::chrono::microseconds>(now - start);
     420              : 
     421            0 :     if (us_since_start.count() > timeout)
     422            0 :       throw VLCommandReplyBufferFlagTimeout(ERS_HERE, timeout);
     423              : 
     424            0 :     std::this_thread::sleep_for(std::chrono::microseconds(50));
     425            0 :   }
     426              :     
     427            0 :   auto rx_packet = getNode("acmd_buf.rxbuf").readBlock(0x20);
     428            0 :   getClient().dispatch();
     429              : 
     430            0 :   if (rx_packet.at(0) != 0xff || rx_packet.at(1) != 0xff || rx_packet.at(2) != packet.at(2))
     431              :   {
     432            0 :     ers::warning(InvalidVLCommandReplyPacket(ERS_HERE, rx_packet.at(0), rx_packet.at(1), rx_packet.at(2)));
     433              :   }
     434              : 
     435            0 :   TLOG_DEBUG(11) << "async result: ";
     436            0 :   for (auto r : rx_packet)
     437            0 :     TLOG_DEBUG(11) << std::hex << "0x" << r;
     438              :   
     439            0 :   return rx_packet.value();
     440            0 : }
     441              : //-----------------------------------------------------------------------------
     442              : 
     443              : //-----------------------------------------------------------------------------
     444              : void
     445            0 : MasterNode::write_endpoint_data(uint16_t endpoint_address, uint8_t reg_address, std::vector<uint8_t> data, bool address_mode) const
     446              : {
     447            0 :   auto data_length = data.size();
     448            0 :   if (data_length > 0x3f || data_length == 0)
     449              :   {
     450            0 :     TLOG() << "invalid data length";
     451              :   }
     452              : 
     453              :   // TODO make sequence a function argument?
     454            0 :   uint32_t sequence = 0xab;
     455              :   
     456            0 :   std::vector<uint32_t> tx_packet = { static_cast<uint32_t>(endpoint_address & 0xff), 
     457            0 :                                       static_cast<uint32_t>(endpoint_address >> 8UL), 
     458              :                                       sequence, 
     459              :                                       // bit 7 = 1 -> write
     460            0 :                                       static_cast<uint32_t>((0x1 << 7UL) | reg_address),
     461            0 :                                        static_cast<uint32_t>((address_mode << 7UL) | (0x3f & data_length))
     462            0 :                                     };
     463            0 :   tx_packet.insert(tx_packet.end(), data.begin(), data.end());
     464            0 :   tx_packet.back() = tx_packet.back() | (0x1 << 8UL);
     465              : 
     466            0 :   auto result = transmit_async_packet(tx_packet);
     467            0 : }
     468              : //-----------------------------------------------------------------------------
     469              : 
     470              : //-----------------------------------------------------------------------------
     471              : std::vector<uint32_t>
     472            0 : MasterNode::read_endpoint_data(uint16_t endpoint_address, uint8_t reg_address, uint8_t data_length, bool address_mode) const
     473              : {
     474            0 :   if (data_length > 0x3f || data_length == 0)
     475              :   {
     476            0 :     TLOG() << "invalid data length";
     477              :     // TODO throw something
     478              :   }
     479              : 
     480              :   // TODO make sequence a function argument?
     481            0 :   uint32_t sequence = 0xab;
     482            0 :   std::vector<uint32_t> tx_packet = { static_cast<uint32_t>(endpoint_address & 0xff), 
     483            0 :                                       static_cast<uint32_t>(endpoint_address >> 8UL), 
     484              :                                       sequence,
     485              :                                       // bit 7 = 0 -> read
     486            0 :                                       reg_address,
     487            0 :                                       static_cast<uint32_t>((0x1 << 8UL) | (address_mode << 7UL) | (0x3f & data_length))
     488            0 :                                       };
     489              : 
     490            0 :   auto result = transmit_async_packet(tx_packet);
     491              : 
     492              :   // get parts we actually want
     493            0 :   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            0 :   result_data.back() = result_data.back() & 0xff;
     497              : 
     498            0 :   return result_data;
     499            0 : }
     500              : //-----------------------------------------------------------------------------
     501              : 
     502              : //-----------------------------------------------------------------------------
     503            0 : void MasterNode::disable_timestamp_broadcast() const
     504              : {
     505            0 :   getNode("global.csr.ctrl.ts_en").write(0x0);
     506            0 :   getClient().dispatch();
     507            0 : }
     508              : //-----------------------------------------------------------------------------
     509              : 
     510              : //-----------------------------------------------------------------------------
     511            0 : void MasterNode::enable_timestamp_broadcast() const
     512              : {
     513            0 :   getNode("global.csr.ctrl.ts_en").write(0x1);
     514            0 :   getClient().dispatch();
     515            0 : }
     516              : //-----------------------------------------------------------------------------
     517              : 
     518              : //-----------------------------------------------------------------------------
     519              : timingfirmware::EndpointCheckResult
     520            0 : MasterNode::scan_endpoint(uint16_t endpoint_address, bool control_sfp) const
     521              : {
     522            0 :   timingfirmware::EndpointCheckResult result;
     523            0 :   auto global = getNode<MasterGlobalNode>("global");
     524            0 :   auto echo = getNode<EchoMonitorNode>("echo_mon");
     525              : 
     526            0 :   timingfirmware::EndpointCheckResult endpoint_result;
     527            0 :   endpoint_result.address = endpoint_address;
     528              : 
     529              :   // is endpoint sfp switched on?
     530              :   // are any relevant muxes set to correct channel?
     531            0 :   if (control_sfp)
     532              :   {
     533            0 :     switch_endpoint_sfp(endpoint_address, true);
     534              : 
     535            0 :     millisleep(100);
     536              :   }
     537              : 
     538            0 :   try
     539              :   {
     540            0 :     global.enable_upstream_endpoint();
     541              :   }
     542            0 :   catch (const timing::ReceiverNotReady& e)
     543              :   {
     544            0 :       switch_endpoint_sfp(endpoint_address, false);
     545              : 
     546              :       //ers::error(MonitoredEndpointDead(ERS_HERE, endpoint_address));
     547              : 
     548            0 :       return endpoint_result;
     549            0 :   }
     550              : 
     551            0 :   endpoint_result.alive = true;
     552            0 :   endpoint_result.round_trip_time = echo.send_echo_and_measure_delay();
     553            0 :   TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << " alive. RTT: " << endpoint_result.round_trip_time;
     554              : 
     555            0 :   auto ept_state = read_endpoint_data(endpoint_address, 0x71, 0x1, 0x1).at(0) & 0xf;
     556            0 :   TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << " state: 0x" << std::hex << ept_state;
     557            0 :   endpoint_result.state = ept_state;
     558              : 
     559            0 :   if (ept_state == 0x6)
     560              :   {
     561            0 :     TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", applying delays of: " << 0x0;
     562            0 :     ers::info(MonitoredEndpointDelaySet(ERS_HERE, 0x0, endpoint_address, ept_state));
     563            0 :     apply_endpoint_delay(endpoint_address, 0x0, 0x0, 0x0, false, false);
     564              :       
     565            0 :     endpoint_result.applied_delay = 0x0;
     566              : 
     567            0 :     auto ept_state_after_delays = read_endpoint_data(endpoint_address, 0x71, 0x1, 0x1).at(0) & 0xf;
     568            0 :     TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", state after delays apply: " << ept_state_after_delays;
     569            0 :     endpoint_result.state_after_delay_apply = ept_state_after_delays;
     570              : 
     571            0 :     endpoint_result.round_trip_time_after_delay_apply = echo.send_echo_and_measure_delay();
     572            0 :     TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", RTT after delays apply: " << endpoint_result.round_trip_time_after_delay_apply;
     573              :   }
     574            0 :   else if (ept_state == 0x7 || ept_state == 0x8)
     575              :   {
     576            0 :     TLOG_DEBUG(5) << "Endpoint at address " << endpoint_address << ", delays not needed";
     577              :   }
     578              :   else
     579              :   {
     580            0 :     ers::error(MonitoredEndpointUnexpectedState(ERS_HERE, endpoint_address, ept_state));
     581              :   }
     582              : 
     583            0 :   if (control_sfp)
     584              :   {
     585            0 :     switch_endpoint_sfp(endpoint_address, false);
     586              :   }
     587              : 
     588              :   return endpoint_result;
     589            0 : }
     590              : //-----------------------------------------------------------------------------
     591              : 
     592              : //-----------------------------------------------------------------------------
     593            0 : void MasterNode::configure_endpoint_command_decoder(uint16_t endpoint_address, uint8_t slot, uint8_t command) const
     594              : {
     595            0 :   write_endpoint_data(endpoint_address, 0x60+slot, {command}, true);
     596            0 : }
     597              : //-----------------------------------------------------------------------------
     598              : } // namespace timing
     599              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1