LCOV - code coverage report
Current view: top level - timing/src - FMCIONode.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 79 0
Test Date: 2026-02-16 10:18:04 Functions: 0.0 % 16 0

            Line data    Source code
       1              : /**
       2              :  * @file FMCIONode.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/FMCIONode.hpp"
      10              : 
      11              : #include <string>
      12              : 
      13              : namespace dunedaq {
      14              : namespace timing {
      15              : 
      16            0 : UHAL_REGISTER_DERIVED_NODE(FMCIONode)
      17              : 
      18              : //-----------------------------------------------------------------------------
      19            0 : FMCIONode::FMCIONode(const uhal::Node& node)
      20            0 :   : IONode(node, "uid_i2c", "pll_i2c", "i2caddr", { "PLL", "CDR" }, { "sfp_i2c" })
      21              : {
      22            0 : }
      23              : //-----------------------------------------------------------------------------
      24              : 
      25              : //-----------------------------------------------------------------------------
      26            0 : FMCIONode::~FMCIONode() {}
      27              : //-----------------------------------------------------------------------------
      28              : 
      29              : //-----------------------------------------------------------------------------
      30              : std::string
      31            0 : FMCIONode::get_uid_address_parameter_name() const
      32              : {
      33            0 :   CarrierType carrier_type = convert_value_to_carrier_type(read_carrier_type());
      34              : 
      35            0 :   if (carrier_type == kCarrierNexusVideo || carrier_type == kCarrierAFC) {
      36            0 :     return "FMC_UID_PROM_NEXUS";
      37              :   } else {
      38            0 :     return "FMC_UID_PROM";
      39              :   }
      40              : }
      41              : //-----------------------------------------------------------------------------
      42              : 
      43              : //-----------------------------------------------------------------------------
      44              : std::string
      45            0 : FMCIONode::get_status(bool print_out) const
      46              : {
      47            0 :   std::stringstream status;
      48              : 
      49            0 :   auto subnodes = read_sub_nodes(getNode("csr.stat"));
      50            0 :   status << format_reg_table(subnodes, "FMC IO state");
      51              : 
      52            0 :   if (print_out)
      53            0 :     TLOG() << std::endl << status.str();
      54            0 :   return status.str();
      55            0 : }
      56              : //-----------------------------------------------------------------------------
      57              : 
      58              : //-----------------------------------------------------------------------------
      59              : void
      60            0 : FMCIONode::reset(const std::string& clock_config_file) const
      61              : {
      62            0 :   write_soft_reset_register();
      63              : 
      64            0 :   millisleep(1000);
      65              : 
      66              :   // Reset PLL
      67            0 :   getNode("csr.ctrl.pll_rst").write(0x1);
      68            0 :   getNode("csr.ctrl.pll_rst").write(0x0);
      69            0 :   getClient().dispatch();
      70              : 
      71            0 :   CarrierType carrier_type = convert_value_to_carrier_type(read_carrier_type());
      72              : 
      73              :   // enclustra i2c switch stuff
      74            0 :   if (carrier_type == kCarrierEnclustraA35) {
      75            0 :     try {
      76            0 :       getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
      77            0 :     } catch (const std::exception& e) {
      78            0 :       ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
      79            0 :     }
      80              :   }
      81              : 
      82              :   // Upload config file to PLL
      83            0 :   configure_pll(clock_config_file);
      84              : 
      85              :   // Reset mmcm
      86            0 :   getNode("csr.ctrl.rst").write(0x1);
      87            0 :   getNode("csr.ctrl.rst").write(0x0);
      88            0 :   getClient().dispatch();
      89              : 
      90              :   // Enable sfp tx laser
      91            0 :   getNode("csr.ctrl.sfp_tx_dis").write(0x0);
      92            0 :   getClient().dispatch();
      93              : 
      94            0 :   TLOG() << "Reset done";
      95            0 : }
      96              : //-----------------------------------------------------------------------------
      97              : 
      98              : //-----------------------------------------------------------------------------
      99            0 : void FMCIONode::reset_pll() const
     100              : {
     101            0 : }
     102              : //-----------------------------------------------------------------------------
     103              : 
     104              : //-----------------------------------------------------------------------------
     105              : std::vector<double>
     106            0 : FMCIONode::read_clock_frequencies() const
     107              : {
     108            0 :   std::vector<std::string> clock_names( {"PLL", "CDR"});
     109              :   // using cdr...?
     110            0 :   auto no_cdr = getNode("config.no_cdr").read();
     111            0 :   getClient().dispatch();
     112            0 :   if (no_cdr)
     113              :   {
     114            0 :     clock_names.push_back("SMPL");
     115              :   }
     116              :   
     117            0 :   return getNode<FrequencyCounterNode>("freq").measure_frequencies(clock_names.size());
     118            0 : }
     119              : //-----------------------------------------------------------------------------
     120              : 
     121              : //-----------------------------------------------------------------------------
     122              : std::string
     123            0 : FMCIONode::get_clock_frequencies_table(bool print_out) const
     124              : {
     125            0 :   std::vector<std::string> clock_names( {"PLL", "CDR"});
     126              :   // using cdr...?
     127            0 :   auto no_cdr = getNode("config.no_cdr").read();
     128            0 :   getClient().dispatch();
     129            0 :   if (no_cdr)
     130              :   {
     131            0 :     clock_names.push_back("SMPL");
     132              :   }
     133            0 :   std::stringstream table;
     134            0 :   std::vector<double> frequencies = read_clock_frequencies();
     135            0 :   for (uint8_t i = 0; i < frequencies.size(); ++i) { // NOLINT(build/unsigned)
     136            0 :     table << clock_names.at(i) << " freq: " << std::setprecision(12) << frequencies.at(i) << std::endl;
     137              :   }
     138              :   // TODO add freq validation Stoyan Trilov stoyan.trilov@cern.ch
     139            0 :   if (print_out)
     140            0 :     TLOG() << table.str();
     141            0 :   return table.str();
     142            0 : }
     143              : //-----------------------------------------------------------------------------
     144              : 
     145              : //-----------------------------------------------------------------------------
     146              : bool
     147            0 : FMCIONode::clocks_ok() const
     148              : {
     149            0 :   std::stringstream status;
     150              : 
     151            0 :   auto states = read_sub_nodes(getNode("csr.stat"));
     152              :   //bool pll_ok = states.find("pll_ok")->second.value();
     153            0 :   bool mmcm_ok = states.find("mmcm_ok")->second.value();
     154              :   
     155            0 :   TLOG_DEBUG(5) << ", mmcm ok: " << mmcm_ok;
     156              : 
     157            0 :   return mmcm_ok; // TODO for EPT, check pll lock
     158            0 : }
     159              : //-----------------------------------------------------------------------------
     160              : 
     161              : //-----------------------------------------------------------------------------
     162              : // void
     163              : // FMCIONode::get_info(timinghardwareinfo::TimingFMCMonitorData& mon_data) const
     164              : // {
     165              : 
     166              : //   auto subnodes = read_sub_nodes(getNode("csr.stat"));
     167              : 
     168              : //   mon_data.cdr_lol = subnodes.at("cdr_lol").value();
     169              : //   mon_data.cdr_los = subnodes.at("cdr_los").value();
     170              : //   mon_data.mmcm_ok = subnodes.at("mmcm_ok").value();
     171              : //   mon_data.mmcm_sticky = subnodes.at("mmcm_sticky").value();
     172              : //   mon_data.sfp_flt = subnodes.at("sfp_flt").value();
     173              : //   mon_data.sfp_los = subnodes.at("sfp_los").value();
     174              : // }
     175              : //-----------------------------------------------------------------------------
     176              : 
     177              : //-----------------------------------------------------------------------------
     178              : // void
     179              : // FMCIONode::get_info(opmonlib::InfoCollector& ci, int level) const
     180              : // {
     181              : //   if (level >= 2) {
     182              : //     timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
     183              : //     this->get_pll()->get_info(pll_mon_data);
     184              : //     ci.add(pll_mon_data);
     185              : 
     186              : //     timinghardwareinfo::TimingSFPMonitorData sfp_mon_data;
     187              : //     auto sfp = this->get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
     188              : //     try {
     189              : //       sfp->get_info(sfp_mon_data);
     190              : //       ci.add(sfp_mon_data);
     191              : //     } catch (timing::SFPUnreachable& e) {
     192              : //       // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
     193              : //       TLOG_DEBUG(2) << "Failed to communicate with SFP on i2c bus" << m_sfp_i2c_buses.at(0);
     194              : //     }
     195              : //   }
     196              : //   if (level >= 1) {
     197              : //     timinghardwareinfo::TimingFMCMonitorData mon_data;
     198              : //     this->get_info(mon_data);
     199              : //     ci.add(mon_data);
     200              : //   }
     201              : // }
     202              : //-----------------------------------------------------------------------------
     203              : 
     204              : //-----------------------------------------------------------------------------
     205              : void
     206            0 : FMCIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned)
     207              : {
     208            0 :   validate_sfp_id(sfp_id);
     209              : 
     210            0 :   getNode("csr.ctrl.sfp_tx_dis").write(!turn_on);
     211            0 :   getClient().dispatch();
     212            0 : }
     213              : //-----------------------------------------------------------------------------
     214              : 
     215              : //-----------------------------------------------------------------------------
     216              : void
     217            0 : FMCIONode::validate_sfp_id(uint32_t sfp_id) const
     218              : { // NOLINT(build/unsigned)
     219              :   // on this board we have 3 upstream SFPs
     220            0 :   if (sfp_id != 0)
     221              :   {
     222            0 :     throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
     223              :   }
     224            0 : }
     225              : //-----------------------------------------------------------------------------
     226              : } // namespace timing
     227              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1