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

            Line data    Source code
       1              : /**
       2              :  * @file TimestampGeneratorNode.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/TimestampGeneratorNode.hpp"
      10              : 
      11              : #include "timing/toolbox.hpp"
      12              : #include "logging/Logging.hpp"
      13              : 
      14              : #include <string>
      15              : 
      16              : namespace dunedaq {
      17              : namespace timing {
      18              : 
      19            0 : UHAL_REGISTER_DERIVED_NODE(TimestampGeneratorNode)
      20              : 
      21              : //-----------------------------------------------------------------------------
      22            0 : TimestampGeneratorNode::TimestampGeneratorNode(const uhal::Node& node)
      23            0 :   : TimingNode(node)
      24            0 : {}
      25              : //-----------------------------------------------------------------------------
      26              : 
      27              : //-----------------------------------------------------------------------------
      28            0 : TimestampGeneratorNode::~TimestampGeneratorNode() {}
      29              : //-----------------------------------------------------------------------------
      30              : 
      31              : //-----------------------------------------------------------------------------
      32              : std::string
      33            0 : TimestampGeneratorNode::get_status(bool print_out) const
      34              : {
      35            0 :   std::stringstream status;
      36            0 :   status << "Current timestamp: 0x" << std::hex << read_timestamp() << std::endl;
      37            0 :   status << "Start timestamp:   0x" << std::hex << read_start_timestamp() << std::endl;
      38            0 :   status << "SW init timestamp: 0x" << std::hex << read_sw_init_timestamp() << std::endl;
      39              : 
      40            0 :   auto ctrl_subnodes = read_sub_nodes(getNode("csr.ctrl"));
      41            0 :   status << format_reg_table(ctrl_subnodes, "TS gen ctrl");
      42              : 
      43            0 :   auto stat_subnodes = read_sub_nodes(getNode("csr.stat"));
      44            0 :   status << format_reg_table(stat_subnodes, "TS gen state");
      45              : 
      46              : 
      47            0 :   if (print_out)
      48            0 :     TLOG() << status.str();
      49            0 :   return status.str();
      50            0 : }
      51              : //-----------------------------------------------------------------------------
      52              : 
      53              : //-----------------------------------------------------------------------------
      54              : uhal::ValVector<uint32_t> // NOLINT(build/unsigned)
      55            0 : TimestampGeneratorNode::read_raw_timestamp(bool dispatch) const
      56              : {
      57            0 :   auto timestamp = getNode("ctr").readBlock(2);
      58            0 :   if (dispatch)
      59            0 :     getClient().dispatch();
      60            0 :   return timestamp;
      61            0 : }
      62              : //-----------------------------------------------------------------------------
      63              : 
      64              : //-----------------------------------------------------------------------------
      65              : uint64_t // NOLINT(build/unsigned)
      66            0 : TimestampGeneratorNode::read_timestamp() const
      67              : {
      68            0 :   return tstamp2int(read_raw_timestamp());
      69              : }
      70              : //-----------------------------------------------------------------------------
      71              : 
      72              : //-----------------------------------------------------------------------------
      73              : uint64_t // NOLINT(build/unsigned)
      74            0 : TimestampGeneratorNode::read_start_timestamp() const
      75              : {
      76            0 :   auto start_ts_l = getNode("csr.tstamp_start_l").read();
      77            0 :   auto start_ts_h = getNode("csr.tstamp_start_h").read();
      78            0 :   getClient().dispatch();
      79            0 :   return (uint64_t)start_ts_l.value() + ((uint64_t)start_ts_h.value() << 32);
      80            0 : }
      81              : //-----------------------------------------------------------------------------
      82              : 
      83              : //-----------------------------------------------------------------------------
      84              : uint64_t // NOLINT(build/unsigned)
      85            0 : TimestampGeneratorNode::read_sw_init_timestamp() const
      86              : {
      87            0 :   auto sw_init_ts_l = getNode("csr.tstamp_sw_init_l").read();
      88            0 :   auto sw_init_ts_h = getNode("csr.tstamp_sw_init_h").read();
      89            0 :   getClient().dispatch();
      90            0 :   return (uint64_t)sw_init_ts_l.value() + ((uint64_t)sw_init_ts_h.value() << 32);
      91            0 : }
      92              : //-----------------------------------------------------------------------------
      93              : 
      94              : //-----------------------------------------------------------------------------
      95              : void
      96            0 : TimestampGeneratorNode::set_timestamp(TimestampSource source) const // NOLINT(build/unsigned)
      97              : {
      98              :   // TODO put somewhere more accessible
      99            0 :   const uint clock_frequency_hz = 62500000;
     100              : 
     101            0 :   const uint64_t old_timestamp = read_timestamp(); // NOLINT(build/unsigned)
     102            0 :   TLOG() << "Reading old timestamp: " << format_reg_value(old_timestamp) << ", " << format_timestamp(old_timestamp, clock_frequency_hz);
     103              : 
     104            0 :   getNode("csr.ctrl.rst").write(0x1);
     105            0 :   getNode("csr.ctrl.tstamp_source_sel").write(source);
     106            0 :   getClient().dispatch();
     107              : 
     108            0 :   uint64_t now_timestamp;
     109            0 :   if (source == kSoftware)
     110              :   {
     111            0 :     now_timestamp = get_milliseconds_since_epoch() * (clock_frequency_hz / 1000); // NOLINT(build/unsigned)
     112              :   }
     113            0 :   else if (source == kMixed)
     114              :   {
     115            0 :     now_timestamp = get_seconds_since_epoch() * clock_frequency_hz ; // NOLINT(build/unsigned)
     116              :   }
     117            0 :   else if (source != kUpstream)
     118              :   {
     119            0 :     throw UnknownTimestampSource(ERS_HERE, source);
     120              :   }
     121              : 
     122            0 :   if (source != kUpstream)
     123              :   {
     124            0 :     TLOG() << "New software timestamp: " << format_reg_value(now_timestamp) << ", " << format_timestamp(now_timestamp, clock_frequency_hz);
     125              :     // Take the timestamp and split it up
     126            0 :     uint32_t now_ts_low = (now_timestamp >> 0) & ((1UL << 32) - 1);  // NOLINT(build/unsigned)
     127            0 :     uint32_t now_ts_high = (now_timestamp >> 32) & ((1UL << 32) - 1); // NOLINT(build/unsigned)
     128              : 
     129            0 :     getNode("csr.tstamp_sw_init_l").write(now_ts_low);
     130            0 :     getNode("csr.tstamp_sw_init_h").write(now_ts_high);
     131              :   }
     132              : 
     133            0 :   getNode("csr.ctrl.rst").write(0x0);
     134            0 :   getNode("csr.ctrl.load").write(0x1);
     135            0 :   getNode("csr.ctrl.load").write(0x0);
     136            0 :   getClient().dispatch();
     137              : 
     138            0 :   auto start = std::chrono::high_resolution_clock::now();
     139            0 :   while (true) {
     140            0 :     auto ts_loaded = getNode("csr.stat.tstamp_loaded").read();
     141            0 :     auto ts_error = getNode("csr.stat.tstamp_error").read();
     142            0 :     getClient().dispatch();
     143              : 
     144            0 :     TLOG_DEBUG(6) << std::hex << "ts loaded: 0x" << ts_loaded.value() << ", ts error: " << ts_error.value();
     145              : 
     146            0 :     if (ts_loaded.value() && !ts_error.value())
     147              :     {
     148            0 :       const uint64_t start_ts = read_start_timestamp();
     149            0 :       TLOG() << "Timestamp initialised with: " << format_reg_value(start_ts) << ", " << format_timestamp(start_ts, clock_frequency_hz);
     150            0 :       break;
     151              :     }
     152              : 
     153            0 :     auto now = std::chrono::high_resolution_clock::now();
     154            0 :     auto ms_since_start = std::chrono::duration_cast<std::chrono::milliseconds>(now - start);
     155              : 
     156            0 :     if (ms_since_start.count() > 1000)
     157            0 :       throw TimestampNotReady(ERS_HERE, ts_loaded.value(), ts_error.value());
     158              : 
     159            0 :     std::this_thread::sleep_for(std::chrono::microseconds(10));
     160            0 :   }
     161              : 
     162            0 :   const uint64_t new_timestamp = read_timestamp(); // NOLINT(build/unsigned)
     163            0 :   TLOG() << "Reading new timestamp: " << format_reg_value(new_timestamp) << ", " << format_timestamp(new_timestamp, clock_frequency_hz);
     164              : 
     165            0 :   getClient().dispatch();
     166            0 : }
     167              : //-----------------------------------------------------------------------------
     168              : 
     169              : } // namespace timing
     170              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1