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

            Line data    Source code
       1              : /**
       2              :  * @file MIBIONode.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/MIBIONode.hpp"
      10              : 
      11              : #include <string>
      12              : #include <math.h>
      13              : 
      14              : namespace dunedaq {
      15              : namespace timing {
      16              : 
      17            0 : UHAL_REGISTER_DERIVED_NODE(MIBIONode)
      18              : 
      19              : //-----------------------------------------------------------------------------
      20            0 : MIBIONode::MIBIONode(const uhal::Node& node)
      21            0 :   : IONode(node, "i2c", "i2c", { "PLL" }, { "PLL", "CDR 0", "CDR 1" }, { "i2c" })
      22              : {
      23            0 : }
      24              : //-----------------------------------------------------------------------------
      25              : 
      26              : //-----------------------------------------------------------------------------
      27            0 : MIBIONode::~MIBIONode() {}
      28              : //-----------------------------------------------------------------------------
      29              : 
      30              : //-----------------------------------------------------------------------------
      31              : std::string
      32            0 : MIBIONode::get_uid_address_parameter_name() const
      33              : {
      34            0 :   return "UID_PROM";
      35              : }
      36              : //-----------------------------------------------------------------------------
      37              : 
      38              : //-----------------------------------------------------------------------------
      39              : std::string
      40            0 : MIBIONode::get_status(bool print_out) const
      41              : {
      42            0 :   std::stringstream status;
      43              : 
      44            0 :   auto subnodes = read_sub_nodes(getNode("csr.stat"));
      45            0 :   status << format_reg_table(subnodes, "MIB IO state");
      46              : 
      47            0 :   if (print_out)
      48            0 :     TLOG() << std::endl << status.str();
      49            0 :   return status.str();
      50            0 : }
      51              : //-----------------------------------------------------------------------------
      52              : 
      53              : //-----------------------------------------------------------------------------
      54              : void
      55            0 : MIBIONode::configure_pll(const std::string& clock_config_file) const
      56              : {
      57              :   // enable pll channel (#3) only
      58            0 :   auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
      59            0 :   i2c_switch->set_channels_states(8);
      60            0 :   IONode::configure_pll(clock_config_file);
      61            0 : }
      62              : //-----------------------------------------------------------------------------
      63              : 
      64              : //-----------------------------------------------------------------------------
      65              : std::string
      66            0 : MIBIONode::get_pll_status(bool print_out) const
      67              : {
      68              :   // enable pll channel (#3) only
      69            0 :   auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
      70            0 :   i2c_switch->set_channels_states(8);
      71            0 :   return IONode::get_pll_status(print_out);
      72            0 : }
      73              : //-----------------------------------------------------------------------------
      74              : 
      75              : //-----------------------------------------------------------------------------
      76              : void
      77            0 : MIBIONode::reset(const std::string& clock_config_file) const
      78              : {
      79            0 :   write_soft_reset_register();
      80              : 
      81            0 :   millisleep(1000);
      82              : 
      83              :   // Upload config file to PLL
      84            0 :   configure_pll(clock_config_file);
      85              : 
      86              :   // Reset mmcm
      87            0 :   getNode("csr.ctrl.rst").write(0x1);
      88            0 :   getNode("csr.ctrl.rst").write(0x0);
      89              : 
      90            0 :   getNode("io_select.csr.ctrl.amc_out").write(0xfff);
      91            0 :   getNode("io_select.csr.ctrl.amc_in").write(0x0);
      92            0 :   getNode("io_select.csr.ctrl.usfp_src").write(0x0);
      93              : 
      94            0 :   getClient().dispatch();
      95              : 
      96            0 :   TLOG() << "Reset done";
      97            0 : }
      98              : //-----------------------------------------------------------------------------
      99              : 
     100              : //-----------------------------------------------------------------------------
     101            0 : void MIBIONode::reset_pll() const
     102              : {
     103            0 : }
     104              : //-----------------------------------------------------------------------------
     105              : 
     106              : //-----------------------------------------------------------------------------
     107              : bool
     108            0 : MIBIONode::clocks_ok() const
     109              : {
     110            0 :   TLOG() << "clock check needs to be implemented";
     111            0 :   return false;
     112              : }
     113              : //-----------------------------------------------------------------------------
     114              : 
     115              : //-----------------------------------------------------------------------------
     116              : //void
     117              : //MIBIONode::switch_downstream_mux_channel(uint32_t mux_channel) const // NOLINT(build/unsigned)
     118              : //{
     119              : //  validate_amc_slot(mux_channel);
     120              : // uint16_t amc_in_bit = 0x1 << (mux_channel-1);
     121              : //  getNode("io_select.csr.ctrl.amc_in").write(amc_in_bit);
     122              : //
     123              : //  TLOG_DEBUG(3) << " MIB downstream AMC (in) " << mux_channel << " enabled";
     124              : //  getClient().dispatch();
     125              : //}
     126              : //-----------------------------------------------------------------------------
     127              : 
     128              : //-----------------------------------------------------------------------------
     129              : //uint32_t // NOLINT(build/unsigned)
     130              : //MIBIONode::read_active_downstream_mux_channel() const
     131              : //{
     132              : //  auto active_mux_channel_bits = getNode("io_select.csr.ctrl.amc_in").read();
     133              : //  getClient().dispatch();
     134              : //  double mux = log2(active_mux_channel_bits.value());
     135              : //  return mux+1;
     136              : //}
     137              : //-----------------------------------------------------------------------------
     138              : 
     139              : //-----------------------------------------------------------------------------
     140              : //void
     141              : //MIBIONode::switch_upstream_mux_channel(uint32_t mux_channel) const // NOLINT(build/unsigned)
     142              : //{
     143              : //  getNode("io_select.csr.ctrl.usfp_src").write(mux_channel);
     144              : //  TLOG_DEBUG(3) << " MIB upstream SFP (in) " << mux_channel << " enabled";
     145              : //  // TODO what about clock config?
     146              : //  getClient().dispatch();
     147              : //}
     148              : //-----------------------------------------------------------------------------
     149              : 
     150              : //-----------------------------------------------------------------------------
     151              : //uint32_t // NOLINT(build/unsigned)
     152              : //MIBIONode::read_active_upstream_mux_channel() const
     153              : //{
     154              : //  auto active_sfp_mux_channel = getNode("io_select.csr.ctrl.usfp_src").read();
     155              : //  getClient().dispatch();
     156              : //  return active_sfp_mux_channel.value();
     157              : //}
     158              : //-----------------------------------------------------------------------------
     159              : 
     160              : //-----------------------------------------------------------------------------
     161              : std::string
     162            0 : MIBIONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
     163            0 :   std::stringstream status;
     164              :   
     165            0 :   validate_sfp_id(sfp_id);
     166              : 
     167              :   // enable i2c path for sfp
     168            0 :   auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
     169            0 :   i2c_switch->set_channels_states(1UL << sfp_id);
     170              : 
     171            0 :   auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
     172              : 
     173            0 :   status << "SFP " << sfp_id << ":" << std::endl;
     174              :   
     175            0 :   try
     176              :   {
     177            0 :     status << sfp->get_status();
     178              :   }
     179            0 :   catch(...)
     180              :   {
     181            0 :     i2c_switch->set_channels_states(8);
     182            0 :     throw;
     183            0 :   }
     184              : 
     185            0 :   i2c_switch->set_channels_states(8);
     186              : 
     187            0 :   if (print_out)
     188            0 :     TLOG() << status.str();
     189              : 
     190            0 :   return status.str();
     191            0 : }
     192              : //-----------------------------------------------------------------------------
     193              : 
     194              : //-----------------------------------------------------------------------------
     195              : void
     196            0 : MIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
     197            0 :   validate_sfp_id(sfp_id);
     198              : 
     199            0 :   auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
     200            0 :   i2c_switch->set_channels_states(1UL << sfp_id);
     201            0 :   auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
     202            0 :   sfp->switch_soft_tx_control_bit(turn_on);
     203            0 :   i2c_switch->set_channels_states(8);
     204            0 : }
     205              : //-----------------------------------------------------------------------------
     206              : 
     207              : //-----------------------------------------------------------------------------
     208              : // void
     209              : // MIBIONode::get_info(timinghardwareinfo::TimingMIBMonitorData& mon_data) const
     210              : // {
     211              : 
     212              : //   auto subnodes = read_sub_nodes(getNode("csr.stat"));
     213              : 
     214              : //   mon_data.cdr_0_lol = subnodes.at("cdr_lol").value() & 0x1;
     215              : //   mon_data.cdr_1_lol = subnodes.at("cdr_lol").value() & 0x2;
     216              : 
     217              : //   mon_data.cdr_0_los = subnodes.at("cdr_los").value() & 0x1;
     218              : //   mon_data.cdr_1_los = subnodes.at("cdr_los").value() & 0x2;
     219              : 
     220              : //   mon_data.mmcm_ok = subnodes.at("mmcm_ok").value();
     221              : //   mon_data.mmcm_sticky = subnodes.at("mmcm_sticky").value();
     222              :   
     223              : //   mon_data.sfp_0_flt = subnodes.at("sfp_flt").value() & 0x1;
     224              : //   mon_data.sfp_1_flt = subnodes.at("sfp_flt").value() & 0x2;
     225              : 
     226              : //   mon_data.sfp_0_los = subnodes.at("sfp_los").value() & 0x1;
     227              : //   mon_data.sfp_1_los = subnodes.at("sfp_los").value() & 0x2;
     228              : 
     229              : //   // TODO 3rd SFP?
     230              : // }
     231              : // //-----------------------------------------------------------------------------
     232              : 
     233              : // //-----------------------------------------------------------------------------
     234              : // void
     235              : // MIBIONode::get_info(opmonlib::InfoCollector& ci, int level) const
     236              : // {
     237              : //   auto i2c_switch = get_i2c_device<I2C9546SwitchSlave>("i2c", "TCA9546_Switch");
     238              : 
     239              : //   if (level >= 2) {
     240              : //     i2c_switch->set_channels_states(8);
     241              : 
     242              : //     timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
     243              : //     get_pll()->get_info(pll_mon_data);
     244              : //     ci.add(pll_mon_data);
     245              :     
     246              : //     for (uint i=0; i < 3; ++i)
     247              : //     {
     248              : //       opmonlib::InfoCollector sfp_ic;
     249              :       
     250              : //       // enable i2c path for sfp
     251              : //       i2c_switch->set_channels_states(1UL << i);
     252              : 
     253              : //       auto sfp = this->get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(0), "SFP_EEProm");
     254              :       
     255              : //       try
     256              : //       {
     257              : //         sfp->get_info(sfp_ic, level);
     258              : //       }
     259              : //       catch (timing::SFPUnreachable& e)
     260              : //       {
     261              : //         // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
     262              : //         TLOG_DEBUG(2) << "Failed to communicate with SFP " << i <<  " on I2C switch channel " << (1UL << i) << " on i2c bus" << m_sfp_i2c_buses.at(0);
     263              : //         continue;
     264              : //       }
     265              : //       ci.add("sfp_"+std::to_string(i),sfp_ic);
     266              : //     }
     267              : //     i2c_switch->set_channels_states(8);
     268              : //   }
     269              : //   if (level >= 1) {
     270              : //     timinghardwareinfo::TimingMIBMonitorData mon_data;
     271              : //     this->get_info(mon_data);
     272              : //     ci.add(mon_data);
     273              : //   }
     274              : // }
     275              : //-----------------------------------------------------------------------------
     276              : 
     277              : //-----------------------------------------------------------------------------
     278              : void
     279            0 : MIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
     280              :   // on this board we have 3 upstream SFPs
     281            0 :   if (sfp_id > 2) {
     282            0 :         throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
     283              :   }
     284            0 : }
     285              : //-----------------------------------------------------------------------------
     286              : 
     287              : //-----------------------------------------------------------------------------
     288              : void
     289            0 : MIBIONode::validate_amc_slot(uint32_t amc_slot) const { // NOLINT(build/unsigned)
     290            0 :   if (amc_slot < 1 || amc_slot > 12) {
     291            0 :         throw InvalidAMCSlot(ERS_HERE, format_reg_value(amc_slot, 10));
     292              :   }
     293            0 : }
     294              : //-----------------------------------------------------------------------------
     295              : } // namespace timing
     296              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1