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

            Line data    Source code
       1              : /**
       2              :  * @file HSINode.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/HSINode.hpp"
      10              : 
      11              : #include "timing/FLCmdGeneratorNode.hpp"
      12              : #include "timing/toolbox.hpp"
      13              : #include "logging/Logging.hpp"
      14              : 
      15              : #include <string>
      16              : #include <utility>
      17              : #include <vector>
      18              : 
      19              : namespace dunedaq {
      20              : namespace timing {
      21              : 
      22            0 : UHAL_REGISTER_DERIVED_NODE(HSINode)
      23              : 
      24              : //-----------------------------------------------------------------------------
      25            0 : HSINode::HSINode(const uhal::Node& node)
      26            0 :   : TimingNode(node)
      27            0 : {}
      28              : //-----------------------------------------------------------------------------
      29              : 
      30              : //-----------------------------------------------------------------------------
      31            0 : HSINode::~HSINode() {}
      32              : //-----------------------------------------------------------------------------
      33              : 
      34              : //-----------------------------------------------------------------------------
      35              : std::string
      36            0 : HSINode::get_status(bool print_out) const
      37              : {
      38              : 
      39            0 :   std::stringstream status;
      40              : 
      41            0 :   std::vector<std::pair<std::string, std::string>> ept_summary;
      42            0 :   std::vector<std::pair<std::string, std::string>> hsi_summary;
      43              : 
      44              :   // auto lEPTimestamp = getNode("tstamp").readBlock(2);
      45              : 
      46            0 :   auto hsi_control = read_sub_nodes(getNode("csr.ctrl"), false);
      47            0 :   auto hsi_state = read_sub_nodes(getNode("csr.stat"), false);
      48              : 
      49            0 :   auto hsi_buffer_count = getNode("buf.count").read();
      50              : 
      51            0 :   auto hsi_re_mask = getNode("csr.re_mask").read();
      52            0 :   auto hsi_fe_mask = getNode("csr.fe_mask").read();
      53            0 :   auto hsi_inv_mask = getNode("csr.inv_mask").read();
      54              : 
      55            0 :   getClient().dispatch();
      56              : 
      57            0 :   hsi_summary.push_back(std::make_pair("Source", format_reg_value(hsi_control.find("src")->second.value(), 16)));
      58            0 :   hsi_summary.push_back(std::make_pair("Enabled", format_reg_value(hsi_control.find("en")->second.value(), 16)));
      59            0 :   hsi_summary.push_back(std::make_pair("Rising edge mask", format_reg_value(hsi_re_mask.value(), 16)));
      60            0 :   hsi_summary.push_back(std::make_pair("Falling edge mask", format_reg_value(hsi_fe_mask.value(), 16)));
      61            0 :   hsi_summary.push_back(std::make_pair("Invert mask", format_reg_value(hsi_inv_mask.value(), 16)));
      62            0 :   hsi_summary.push_back(
      63            0 :     std::make_pair("Buffer enabled", format_reg_value(hsi_control.find("buf_en")->second.value(), 16)));
      64            0 :   hsi_summary.push_back(
      65            0 :     std::make_pair("Buffer error", format_reg_value(hsi_state.find("buf_err")->second.value(), 16)));
      66            0 :   hsi_summary.push_back(
      67            0 :     std::make_pair("Buffer warning", format_reg_value(hsi_state.find("buf_warn")->second.value(), 16)));
      68            0 :   hsi_summary.push_back(std::make_pair("Buffer occupancy", to_string(hsi_buffer_count.value())));
      69              : 
      70            0 :   status << format_reg_table(hsi_summary, "HSI summary", { "", "" }) << std::endl;
      71              : 
      72            0 :   if (print_out)
      73            0 :     TLOG() << status.str();
      74            0 :   return status.str();
      75            0 : }
      76              : //-----------------------------------------------------------------------------
      77              : 
      78              : //-----------------------------------------------------------------------------
      79              : uint32_t // NOLINT(build/unsigned)
      80            0 : HSINode::read_buffer_count() const
      81              : {
      82            0 :   auto buffer_count = getNode("buf.count").read();
      83            0 :   getClient().dispatch();
      84            0 :   return buffer_count.value();
      85            0 : }
      86              : //-----------------------------------------------------------------------------
      87              : 
      88              : //-----------------------------------------------------------------------------
      89              : uhal::ValVector<uint32_t>                                                             // NOLINT(build/unsigned)
      90            0 : HSINode::read_data_buffer(uint16_t& n_words, bool read_all, bool fail_on_error) const // NOLINT(build/unsigned)
      91              : {
      92              : 
      93            0 :   uint32_t buffer_state = read_buffer_state(); // NOLINT(build/unsigned)
      94              : 
      95            0 :   uint16_t n_hsi_words = buffer_state >> 0x10; // NOLINT(build/unsigned)
      96              : 
      97            0 :   n_words = n_hsi_words;
      98              : 
      99            0 :   TLOG_DEBUG(5) << "Words available in readout buffer:      " << format_reg_value(n_hsi_words);
     100              : 
     101            0 :   uhal::ValVector<uint32_t> buffer_data; // NOLINT(build/unsigned)
     102              : 
     103            0 :   if (buffer_state & 0x2) {
     104            0 :     ers::warning(HSIBufferIssue(ERS_HERE, "WARNING"));
     105              :   }
     106              : 
     107            0 :   if (buffer_state & 0x1) {
     108            0 :     ers::error(HSIBufferIssue(ERS_HERE, "ERROR"));
     109            0 :     if (fail_on_error)
     110              :       return buffer_data;
     111              :   }
     112              : 
     113              :   // this is bad
     114            0 :   if (n_hsi_words > 1024) {
     115            0 :     ers::error(HSIBufferIssue(ERS_HERE, "OVERFLOW"));
     116            0 :     if (fail_on_error)
     117              :       return buffer_data;
     118              :     n_hsi_words = 1024;
     119              :   }
     120              : 
     121            0 :   uint32_t events_to_read = n_hsi_words / hsi_buffer_event_words_number; // NOLINT(build/unsigned)
     122              : 
     123            0 :   TLOG_DEBUG(5) << "Events available in readout buffer:     " << format_reg_value(events_to_read);
     124              : 
     125            0 :   uint32_t words_to_read = read_all ? n_hsi_words : events_to_read * hsi_buffer_event_words_number; // NOLINT(build/unsigned)
     126              : 
     127            0 :   TLOG_DEBUG(5) << "Words to be read out in readout buffer: " << format_reg_value(words_to_read);
     128              : 
     129            0 :   if (!words_to_read) {
     130            0 :     TLOG_DEBUG(5) << "No words to be read out.";
     131              :   }
     132              : 
     133            0 :   buffer_data = getNode("buf.data").readBlock(words_to_read);
     134            0 :   getClient().dispatch();
     135              : 
     136              :   return buffer_data;
     137            0 : }
     138              : //-----------------------------------------------------------------------------
     139              : 
     140              : //-----------------------------------------------------------------------------
     141              : uhal::ValVector<uint32_t> // NOLINT(build/unsigned)
     142            0 : HSINode::read_data_buffer(bool read_all, bool fail_on_error) const
     143              : {
     144            0 :   uint16_t words; // NOLINT(build/unsigned)
     145            0 :   return read_data_buffer(words, read_all, fail_on_error);
     146              : }
     147              : 
     148              : //-----------------------------------------------------------------------------
     149              : std::string
     150            0 : HSINode::get_data_buffer_table(bool read_all, bool print_out) const
     151              : {
     152              : 
     153            0 :   std::stringstream table;
     154            0 :   auto buffer_data = read_data_buffer(read_all);
     155              : 
     156            0 :   std::vector<std::pair<std::string, uint32_t>> buffer_table; // NOLINT(build/unsigned)
     157              : 
     158            0 :   uint32_t i = 0; // NOLINT(build/unsigned)
     159            0 :   for (auto it = buffer_data.begin(); it != buffer_data.end(); ++it, ++i) {
     160            0 :     std::stringstream index_stream;
     161            0 :     index_stream << std::setfill('0') << std::setw(4) << i;
     162            0 :     buffer_table.push_back(std::make_pair(index_stream.str(), *it));
     163            0 :   }
     164            0 :   table << format_reg_table(buffer_table, "HSI buffer", { "Word", "Data" });
     165              : 
     166            0 :   if (print_out)
     167            0 :     TLOG() << table.str();
     168            0 :   return table.str();
     169            0 : }
     170              : //-----------------------------------------------------------------------------
     171              : 
     172              : //-----------------------------------------------------------------------------
     173              : void
     174            0 : HSINode::configure_hsi(uint32_t src,      // NOLINT(build/unsigned)
     175              :                        uint32_t re_mask,  // NOLINT(build/unsigned)
     176              :                        uint32_t fe_mask,  // NOLINT(build/unsigned)
     177              :                        uint32_t inv_mask, // NOLINT(build/unsigned)
     178              :                        double rate,
     179              :                        uint32_t clock_frequency_hz, // NOLINT(build/unsigned)
     180              :                        bool dispatch) const
     181              : {
     182              : 
     183            0 :   getNode("csr.ctrl.src").write(src);
     184            0 :   getNode("csr.re_mask").write(re_mask);
     185            0 :   getNode("csr.fe_mask").write(fe_mask);
     186            0 :   getNode("csr.inv_mask").write(inv_mask);
     187              : 
     188              :   // Configures the internal hsi signal generator to produce triggers at a defined frequency.
     189              :   // Rate =  (clock_frequency_hz / 2^(d+8)) / p where n in [0,15] and p in [1,256]
     190              : 
     191              :   // DIVIDER (int): Frequency divider.
     192              : 
     193              :   // The division from clock_frequency_hz to the desired rate is done in three steps:
     194              :   // a) A pre-division by 256
     195              :   // b) Division by a power of two set by n = 2 ^ rate_div_d (ranging from 2^0 -> 2^15)
     196              :   // c) 1-in-n prescaling set by n = rate_div_p
     197              :   
     198            0 :   try
     199              :   {
     200            0 :     uint32_t divisor;
     201            0 :     uint32_t prescale;
     202            0 :     double actual_rate;
     203              : 
     204            0 :     FLCmdGeneratorNode::parse_periodic_fl_cmd_rate(rate, clock_frequency_hz, actual_rate, divisor, prescale);
     205              : 
     206            0 :     TLOG() << "Requested rate, actual rate: " << rate << ", " << actual_rate;
     207            0 :     TLOG() << "prescale, divisor: " << prescale << ", " << divisor;
     208              : 
     209            0 :     std::stringstream trig_stream;
     210            0 :     trig_stream << "> Random trigger rate for HSI set to " << std::setprecision(3) << std::scientific << actual_rate << " Hz. d: " << divisor << " p: " << prescale;
     211            0 :     TLOG() << trig_stream.str();
     212              :     
     213            0 :     getNode("csr.ctrl.rate_div_p").write(prescale);
     214            0 :     getNode("csr.ctrl.rate_div_d").write(divisor);
     215            0 :   }
     216            0 :   catch (const timing::BadRequestedFakeTriggerRate& e)
     217              :   {
     218            0 :     ers::error(FailedToUpdateHSIRandomRate(ERS_HERE,e));
     219            0 :   }
     220              : 
     221            0 :   if (dispatch)
     222            0 :     getClient().dispatch();
     223            0 : }
     224              : //-----------------------------------------------------------------------------
     225              : 
     226              : //-----------------------------------------------------------------------------
     227              : void
     228            0 : HSINode::start_hsi(bool dispatch) const
     229              : {
     230            0 :   getNode("csr.ctrl.en").write(0x1);
     231            0 :   if (dispatch)
     232            0 :     getClient().dispatch();
     233            0 : }
     234              : //-----------------------------------------------------------------------------
     235              : 
     236              : //-----------------------------------------------------------------------------
     237              : void
     238            0 : HSINode::stop_hsi(bool dispatch) const
     239              : {
     240            0 :   getNode("csr.ctrl.en").write(0x0);
     241            0 :   if (dispatch)
     242            0 :     getClient().dispatch();
     243            0 : }
     244              : //-----------------------------------------------------------------------------
     245              : 
     246              : //-----------------------------------------------------------------------------
     247              : void
     248            0 : HSINode::reset_hsi(bool dispatch) const
     249              : {
     250            0 :   getNode("csr.ctrl.en").write(0x0);
     251              : 
     252            0 :   getNode("csr.ctrl.buf_en").write(0x0);
     253            0 :   getNode("csr.ctrl.buf_en").write(0x1);
     254              : 
     255            0 :   getNode("csr.re_mask").write(0x0);
     256            0 :   getNode("csr.fe_mask").write(0x0);
     257            0 :   getNode("csr.inv_mask").write(0x0);
     258            0 :   getNode("csr.ctrl.src").write(0x0);
     259              : 
     260            0 :   if (dispatch)
     261            0 :     getClient().dispatch();
     262            0 : }
     263              : //-----------------------------------------------------------------------------
     264              : 
     265              : //-----------------------------------------------------------------------------
     266              : bool
     267            0 : HSINode::read_buffer_warning() const
     268              : {
     269            0 :   auto buf_warning = getNode("csr.stat.buf_warn").read();
     270            0 :   getClient().dispatch();
     271            0 :   return buf_warning.value();
     272            0 : }
     273              : //-----------------------------------------------------------------------------
     274              : 
     275              : //-----------------------------------------------------------------------------
     276              : bool
     277            0 : HSINode::read_buffer_error() const
     278              : {
     279            0 :   auto buf_error = getNode("csr.stat.buf_err").read();
     280            0 :   getClient().dispatch();
     281            0 :   return buf_error.value();
     282            0 : }
     283              : //-----------------------------------------------------------------------------
     284              : 
     285              : //-----------------------------------------------------------------------------
     286              : uint32_t // NOLINT(build/unsigned)
     287            0 : HSINode::read_buffer_state() const
     288              : {
     289              : 
     290            0 :   auto buf_state = read_sub_nodes(getNode("csr.stat"), false);
     291            0 :   auto hsi_buffer_count = getNode("buf.count").read();
     292            0 :   getClient().dispatch();
     293              : 
     294            0 :   uint8_t buffer_error = static_cast<uint8_t>(buf_state.find("buf_err")->second.value());    // NOLINT(build/unsigned)
     295            0 :   uint8_t buffer_warning = static_cast<uint8_t>(buf_state.find("buf_warn")->second.value()); // NOLINT(build/unsigned)
     296              : 
     297            0 :   uint32_t buffer_state = buffer_error | (buffer_warning << 1);                          // NOLINT(build/unsigned)
     298            0 :   buffer_state = buffer_state | static_cast<uint32_t>(hsi_buffer_count.value()) << 0x10; // NOLINT(build/unsigned)
     299            0 :   return buffer_state;
     300            0 : }
     301              : //-----------------------------------------------------------------------------
     302              : 
     303              : //-----------------------------------------------------------------------------
     304              : uint32_t // NOLINT(build/unsigned)
     305            0 : HSINode::read_signal_source_mode() const
     306              : {
     307            0 :   auto source = getNode("csr.ctrl.src").read();
     308            0 :   getClient().dispatch();
     309            0 :   return source.value();
     310            0 : }
     311              : //-----------------------------------------------------------------------------
     312              : 
     313              : //-----------------------------------------------------------------------------
     314              : void
     315            0 : HSINode::get_info(timingfirmwareinfo::HSIFirmwareMonitorData& mon_data) const
     316              : {
     317            0 :   auto hsi_control = read_sub_nodes(getNode("csr.ctrl"), false);
     318            0 :   auto hsi_state = read_sub_nodes(getNode("csr.stat"), false);
     319              : 
     320            0 :   auto hsi_buffer_count = getNode("buf.count").read();
     321              : 
     322            0 :   auto hsi_re_mask = getNode("csr.re_mask").read();
     323            0 :   auto hsi_fe_mask = getNode("csr.fe_mask").read();
     324            0 :   auto hsi_inv_mask = getNode("csr.inv_mask").read();
     325              : 
     326            0 :   getClient().dispatch();
     327              : 
     328            0 :   mon_data.source = hsi_control.find("src")->second.value();
     329            0 :   mon_data.re_mask = hsi_re_mask.value();
     330            0 :   mon_data.fe_mask = hsi_fe_mask.value();
     331            0 :   mon_data.inv_mask = hsi_inv_mask.value();
     332            0 :   mon_data.buffer_enabled = hsi_control.find("buf_en")->second.value();
     333            0 :   mon_data.buffer_error = hsi_state.find("buf_err")->second.value();
     334            0 :   mon_data.buffer_warning = hsi_state.find("buf_warn")->second.value();
     335            0 :   mon_data.buffer_occupancy = hsi_buffer_count.value();
     336            0 :   mon_data.enabled = hsi_control.find("en")->second.value();
     337            0 : }
     338              : // //-----------------------------------------------------------------------------
     339              : 
     340              : } // namespace timing
     341              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1