LCOV - code coverage report
Current view: top level - timing/src - FMCIONode.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 89 0
Test Date: 2025-12-21 13:07:08 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              : 
      93              :   // rx edges
      94            0 :   uint32_t cdr_rx_edge = 0x0; // NOLINT(build/unsigned)
      95            0 :   uint32_t sfp_rx_edge = 0x0; // NOLINT(build/unsigned)
      96            0 :   uint32_t rj45_rx_edge = 0x0; // NOLINT(build/unsigned)
      97              : 
      98              :   // tx edges
      99            0 :   uint32_t sfp_tx_edge = 0x0; // NOLINT(build/unsigned)
     100            0 :   uint32_t rj45_tx_edge = 0x0; // NOLINT(build/unsigned)
     101              : 
     102              :   // rx edges
     103            0 :   getNode("csr.ctrl.cdr_rx_edge").write(cdr_rx_edge);
     104            0 :   getNode("csr.ctrl.sfp_rx_edge").write(sfp_rx_edge);
     105            0 :   getNode("csr.ctrl.rj45_rx_edge").write(rj45_rx_edge);
     106              : 
     107              :   // tx edges
     108            0 :   getNode("csr.ctrl.sfp_tx_edge").write(sfp_tx_edge);
     109            0 :   getNode("csr.ctrl.rj45_tx_edge").write(rj45_tx_edge);
     110              : 
     111            0 :   getClient().dispatch();
     112              : 
     113            0 :   TLOG() << "Reset done";
     114            0 : }
     115              : //-----------------------------------------------------------------------------
     116              : 
     117              : //-----------------------------------------------------------------------------
     118            0 : void FMCIONode::reset_pll() const
     119              : {
     120            0 : }
     121              : //-----------------------------------------------------------------------------
     122              : 
     123              : //-----------------------------------------------------------------------------
     124              : std::vector<double>
     125            0 : FMCIONode::read_clock_frequencies() const
     126              : {
     127            0 :   std::vector<std::string> clock_names( {"PLL", "CDR"});
     128              :   // using cdr...?
     129            0 :   auto no_cdr = getNode("config.no_cdr").read();
     130            0 :   getClient().dispatch();
     131            0 :   if (no_cdr)
     132              :   {
     133            0 :     clock_names.push_back("SMPL");
     134              :   }
     135              :   
     136            0 :   return getNode<FrequencyCounterNode>("freq").measure_frequencies(clock_names.size());
     137            0 : }
     138              : //-----------------------------------------------------------------------------
     139              : 
     140              : //-----------------------------------------------------------------------------
     141              : std::string
     142            0 : FMCIONode::get_clock_frequencies_table(bool print_out) const
     143              : {
     144            0 :   std::vector<std::string> clock_names( {"PLL", "CDR"});
     145              :   // using cdr...?
     146            0 :   auto no_cdr = getNode("config.no_cdr").read();
     147            0 :   getClient().dispatch();
     148            0 :   if (no_cdr)
     149              :   {
     150            0 :     clock_names.push_back("SMPL");
     151              :   }
     152            0 :   std::stringstream table;
     153            0 :   std::vector<double> frequencies = read_clock_frequencies();
     154            0 :   for (uint8_t i = 0; i < frequencies.size(); ++i) { // NOLINT(build/unsigned)
     155            0 :     table << clock_names.at(i) << " freq: " << std::setprecision(12) << frequencies.at(i) << std::endl;
     156              :   }
     157              :   // TODO add freq validation Stoyan Trilov stoyan.trilov@cern.ch
     158            0 :   if (print_out)
     159            0 :     TLOG() << table.str();
     160            0 :   return table.str();
     161            0 : }
     162              : //-----------------------------------------------------------------------------
     163              : 
     164              : //-----------------------------------------------------------------------------
     165              : bool
     166            0 : FMCIONode::clocks_ok() const
     167              : {
     168            0 :   std::stringstream status;
     169              : 
     170            0 :   auto states = read_sub_nodes(getNode("csr.stat"));
     171              :   //bool pll_ok = states.find("pll_ok")->second.value();
     172            0 :   bool mmcm_ok = states.find("mmcm_ok")->second.value();
     173              :   
     174            0 :   TLOG_DEBUG(5) << ", mmcm ok: " << mmcm_ok;
     175              : 
     176            0 :   return mmcm_ok; // TODO for EPT, check pll lock
     177            0 : }
     178              : //-----------------------------------------------------------------------------
     179              : 
     180              : //-----------------------------------------------------------------------------
     181              : // void
     182              : // FMCIONode::get_info(timinghardwareinfo::TimingFMCMonitorData& mon_data) const
     183              : // {
     184              : 
     185              : //   auto subnodes = read_sub_nodes(getNode("csr.stat"));
     186              : 
     187              : //   mon_data.cdr_lol = subnodes.at("cdr_lol").value();
     188              : //   mon_data.cdr_los = subnodes.at("cdr_los").value();
     189              : //   mon_data.mmcm_ok = subnodes.at("mmcm_ok").value();
     190              : //   mon_data.mmcm_sticky = subnodes.at("mmcm_sticky").value();
     191              : //   mon_data.sfp_flt = subnodes.at("sfp_flt").value();
     192              : //   mon_data.sfp_los = subnodes.at("sfp_los").value();
     193              : // }
     194              : //-----------------------------------------------------------------------------
     195              : 
     196              : //-----------------------------------------------------------------------------
     197              : // void
     198              : // FMCIONode::get_info(opmonlib::InfoCollector& ci, int level) const
     199              : // {
     200              : //   if (level >= 2) {
     201              : //     timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
     202              : //     this->get_pll()->get_info(pll_mon_data);
     203              : //     ci.add(pll_mon_data);
     204              : 
     205              : //     timinghardwareinfo::TimingSFPMonitorData sfp_mon_data;
     206              : //     auto sfp = this->get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
     207              : //     try {
     208              : //       sfp->get_info(sfp_mon_data);
     209              : //       ci.add(sfp_mon_data);
     210              : //     } catch (timing::SFPUnreachable& e) {
     211              : //       // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
     212              : //       TLOG_DEBUG(2) << "Failed to communicate with SFP on i2c bus" << m_sfp_i2c_buses.at(0);
     213              : //     }
     214              : //   }
     215              : //   if (level >= 1) {
     216              : //     timinghardwareinfo::TimingFMCMonitorData mon_data;
     217              : //     this->get_info(mon_data);
     218              : //     ci.add(mon_data);
     219              : //   }
     220              : // }
     221              : //-----------------------------------------------------------------------------
     222              : 
     223              : //-----------------------------------------------------------------------------
     224              : void
     225            0 : FMCIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned)
     226              : {
     227            0 :   validate_sfp_id(sfp_id);
     228              : 
     229            0 :   getNode("csr.ctrl.sfp_tx_dis").write(!turn_on);
     230            0 :   getClient().dispatch();
     231            0 : }
     232              : //-----------------------------------------------------------------------------
     233              : 
     234              : //-----------------------------------------------------------------------------
     235              : void
     236            0 : FMCIONode::validate_sfp_id(uint32_t sfp_id) const
     237              : { // NOLINT(build/unsigned)
     238              :   // on this board we have 3 upstream SFPs
     239            0 :   if (sfp_id != 0)
     240              :   {
     241            0 :     throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
     242              :   }
     243            0 : }
     244              : //-----------------------------------------------------------------------------
     245              : } // namespace timing
     246              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1