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

            Line data    Source code
       1              : /**
       2              :  * @file FIBIONode.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/FIBIONode.hpp"
      10              : 
      11              : #include <map>
      12              : #include <string>
      13              : #include <utility>
      14              : #include <vector>
      15              : 
      16              : namespace dunedaq {
      17              : namespace timing {
      18              : 
      19            0 : UHAL_REGISTER_DERIVED_NODE(FIBIONode)
      20              : 
      21              : //-----------------------------------------------------------------------------
      22            0 : FIBIONode::FIBIONode(const uhal::Node& aNode) :
      23            0 :         SFPMuxIONode(aNode, "i2c", "i2c", "SI5345", {"PLL", "BKP DATA"}, {"i2c_sfp0", "i2c_sfp1", "i2c_sfp2", "i2c_sfp3", "i2c_sfp4", "i2c_sfp5", "i2c_sfp6", "i2c_sfp7"}) {
      24            0 : }
      25              : //-----------------------------------------------------------------------------
      26              : 
      27              : 
      28              : //-----------------------------------------------------------------------------
      29            0 : FIBIONode::~FIBIONode() {
      30            0 : }
      31              : //-----------------------------------------------------------------------------
      32              : 
      33              : //-----------------------------------------------------------------------------
      34              : std::string
      35            0 : FIBIONode::get_uid_address_parameter_name() const
      36              : {
      37            0 :   return "UID_PROM";
      38              : }
      39              : //-----------------------------------------------------------------------------
      40              : 
      41              : //-----------------------------------------------------------------------------
      42              : std::string
      43            0 : FIBIONode::get_status(bool print_out) const {
      44            0 :         std::stringstream status;
      45            0 :         auto subnodes = read_sub_nodes(getNode("csr.stat"));
      46              : 
      47            0 :         uint32_t sfp_los_flags = read_sfp_los_flags(); // NOLINT(build/unsigned)
      48            0 :         uint32_t sfp_fault_flags = read_sfp_fault_flags(); // NOLINT(build/unsigned)
      49              :         
      50            0 :         std::vector<std::pair<std::string, std::string>> sfps_summary;
      51            0 :         sfps_summary.push_back(std::make_pair("SFP LOS flags", format_reg_value(sfp_los_flags, 16)));
      52            0 :         sfps_summary.push_back(std::make_pair("SFP fault flags", format_reg_value(sfp_fault_flags, 16)));
      53              : 
      54            0 :         status << format_reg_table(subnodes, "FIB IO state") << std::endl;
      55            0 :         status << format_reg_table(sfps_summary, "FIB SFPs state");
      56              : 
      57            0 :         if (print_out)
      58            0 :           TLOG() << status.str();
      59              : 
      60            0 :     return status.str();
      61            0 : }
      62              : //-----------------------------------------------------------------------------
      63              : 
      64              : 
      65              : //-----------------------------------------------------------------------------
      66              : void
      67            0 : FIBIONode::reset(const std::string& clock_config_file) const {
      68              :         
      69              :         // Soft reset
      70            0 :         write_soft_reset_register();
      71              :         
      72            0 :         millisleep(1000);
      73              : 
      74              :         // Reset I2C
      75            0 :         getNode("csr.ctrl.rstb_i2c").write(0x1);
      76            0 :         getNode("csr.ctrl.rstb_i2c").write(0x0);
      77              : 
      78            0 :         getNode("csr.ctrl.rst").write(0x1);
      79            0 :         getNode("csr.ctrl.rst").write(0x0);
      80              : 
      81            0 :         getClient().dispatch();
      82              : 
      83            0 :         const CarrierType carrier_type = convert_value_to_carrier_type(read_carrier_type());
      84              : 
      85            0 :         if (carrier_type == kCarrierEnclustraA35) {
      86              :                 // enclustra i2c switch stuff
      87            0 :                 try {
      88            0 :                         getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
      89            0 :                 } catch (const std::exception& e) {
      90            0 :                 ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
      91            0 :         }
      92              :         }
      93              :         
      94              :         // Configure I2C IO expanders
      95            0 :         auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
      96            0 :         auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
      97              : 
      98              :         // Bank 0
      99            0 :         ic_10->set_inversion(0, 0x00);
     100              :         
     101              :         //  all out, sfp tx disable
     102            0 :         ic_10->set_io(0, 0x00);
     103              :         // sfp laser on by default
     104            0 :         ic_10->set_outputs(0, 0x00);
     105              : 
     106              :         // Bank 1
     107            0 :         ic_10->set_inversion(1, 0x00);
     108              :         // all inputs, sfp fault
     109            0 :         ic_10->set_io(1, 0xff);
     110              : 
     111              :         // Bank 0
     112            0 :         ic_23->set_inversion(0, 0x00);
     113              :         // pin 0 - out: pll rst, pins 1-4 pll and cdr flags
     114            0 :         ic_23->set_io(0, 0xfe);
     115            0 :         ic_23->set_outputs(0, 0x01);
     116              : 
     117              :         // Bank 1
     118            0 :         ic_23->set_inversion(1, 0x00);
     119              :         // all inputs, sfp los
     120            0 :         ic_23->set_io(1, 0xff);
     121              : 
     122              :         // reset pll via I2C IO expanders
     123            0 :         reset_pll();
     124              : 
     125              :         // Upload config file to PLL
     126            0 :         configure_pll(clock_config_file);
     127              :         
     128              :         //getNode("csr.ctrl.inmux").write(0);
     129              :         //getClient().dispatch();
     130              :         
     131              : // To be removed from firmware address maps also
     132              : //      getNode("csr.ctrl.rst_lock_mon").write(0x1);
     133              : //      getNode("csr.ctrl.rst_lock_mon").write(0x0);
     134              : //      getClient().dispatch();
     135              : 
     136            0 :         TLOG() << "Reset done";
     137            0 : }
     138              : //-----------------------------------------------------------------------------
     139              : //-----------------------------------------------------------------------------
     140              : void
     141            0 : FIBIONode::switch_sfp_mux_channel(uint32_t mux_channel) const { // NOLINT(build/unsigned)
     142            0 :         validate_sfp_id(mux_channel);
     143            0 :         getNode("csr.ctrl.inmux").write(mux_channel);
     144            0 :         getClient().dispatch(); 
     145            0 :         TLOG_DEBUG(0) << "SFP input mux set to " << read_active_sfp_mux_channel();
     146            0 : }
     147              : //-----------------------------------------------------------------------------
     148              : 
     149              : 
     150              : //-----------------------------------------------------------------------------
     151              : uint32_t // NOLINT(build/unsigned)
     152            0 : FIBIONode::read_active_sfp_mux_channel() const {
     153            0 :         auto active_sfp_mux_channel = getNode("csr.ctrl.inmux").read();
     154            0 :         getClient().dispatch();
     155            0 :         return active_sfp_mux_channel.value();
     156            0 : }
     157              : //-----------------------------------------------------------------------------
     158              : 
     159              : 
     160              : //-----------------------------------------------------------------------------
     161              : std::string
     162            0 : FIBIONode::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            0 :         std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
     168            0 :         auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
     169            0 :         status << "Fanout SFP " << sfp_id << ":" << std::endl;
     170            0 :         status << sfp->get_status();   
     171              :         
     172            0 :         if (print_out)
     173            0 :                 TLOG() << status.str();
     174              : 
     175            0 :         return status.str();
     176            0 : }
     177              : //-----------------------------------------------------------------------------
     178              : 
     179              : 
     180              : //-----------------------------------------------------------------------------
     181              : void
     182            0 : FIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
     183            0 :         validate_sfp_id(sfp_id);
     184              : 
     185              :         // on this board the 8 downstream sfps have their own i2c bus
     186            0 :         std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(sfp_id);
     187            0 :         auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
     188            0 :         sfp->switch_soft_tx_control_bit(turn_on);
     189            0 : }
     190              : //-----------------------------------------------------------------------------
     191              : 
     192              : 
     193              : //-----------------------------------------------------------------------------
     194              : void
     195            0 : FIBIONode::reset_pll() const {
     196            0 :         auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
     197            0 :         ic_23->set_outputs(0, 0x00);
     198            0 :         ic_23->set_outputs(0, 0x01);
     199            0 : }
     200              : //-----------------------------------------------------------------------------
     201              : 
     202              : //-----------------------------------------------------------------------------
     203              : uint8_t // NOLINT(build/unsigned)
     204            0 : FIBIONode::read_sfp_los_flags() const {
     205            0 :         auto ic_23 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander2");
     206              : 
     207            0 :         uint8_t sfp_los_flags = ic_23->read_inputs(0x01); // NOLINT(build/unsigned)
     208            0 :         return sfp_los_flags;
     209            0 : }
     210              : //-----------------------------------------------------------------------------
     211              : 
     212              : 
     213              : //-----------------------------------------------------------------------------
     214              : uint8_t // NOLINT(build/unsigned)
     215            0 : FIBIONode::read_sfp_fault_flags() const {
     216            0 :         auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
     217              :         
     218            0 :         uint8_t sfp_fault_flags = ic_10->read_inputs(0x01); // NOLINT(build/unsigned)
     219            0 :         return sfp_fault_flags;
     220            0 : }
     221              : //-----------------------------------------------------------------------------
     222              : 
     223              : //-----------------------------------------------------------------------------
     224              : uint8_t                                                                                           // NOLINT(build/unsigned)
     225            0 : FIBIONode::read_sfp_los_flag(uint32_t sfp_id) const { // NOLINT(build/unsigned)
     226            0 :         return read_sfp_los_flags() & (1UL << sfp_id);
     227              : }
     228              : //-----------------------------------------------------------------------------
     229              : 
     230              : 
     231              : //-----------------------------------------------------------------------------
     232              : uint8_t                                                                                                 // NOLINT(build/unsigned)
     233            0 : FIBIONode::read_sfp_fault_flag(uint32_t sfp_id) const { // NOLINT(build/unsigned)
     234            0 :         return read_sfp_fault_flags() & (1UL << sfp_id);
     235              : }
     236              : //-----------------------------------------------------------------------------
     237              : 
     238              : 
     239              : //-----------------------------------------------------------------------------
     240              : void
     241            0 : FIBIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
     242            0 :         validate_sfp_id(sfp_id);
     243              :         
     244            0 :         auto ic_10 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "Expander1");
     245            0 :         uint8_t current_sfp_tx_control_flags = ic_10->read_outputs_config(0); // NOLINT(build/unsigned)
     246              : 
     247            0 :         uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
     248            0 :         if (turn_on) 
     249              :         {
     250            0 :                 new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
     251              :         }
     252              :     else 
     253              :     {
     254            0 :         new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
     255              :     }
     256              : 
     257            0 :     ic_10->set_outputs(0, new_sfp_tx_control_flags);
     258            0 : }
     259              : //-----------------------------------------------------------------------------
     260              : 
     261              : //-----------------------------------------------------------------------------
     262              : bool
     263            0 : FIBIONode::clocks_ok() const
     264              : {
     265            0 :   std::stringstream status;
     266              : 
     267            0 :   auto states = read_sub_nodes(getNode("csr.stat"));
     268            0 :   bool pll_ok = states.find("pll_ok")->second.value();
     269            0 :   bool mmcm_ok = states.find("mmcm_ok")->second.value();
     270              : 
     271            0 :   TLOG_DEBUG(5) << "pll ok: " << pll_ok << ", mmcm ok: " << mmcm_ok;
     272              : 
     273            0 :   return pll_ok && mmcm_ok;
     274            0 : }
     275              : //-----------------------------------------------------------------------------
     276              : 
     277              : //-----------------------------------------------------------------------------
     278              : void
     279            0 : FIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
     280              :         // on this board we have 8 downstream SFPs
     281            0 :         if (sfp_id > 7) {
     282            0 :         throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
     283              :         }
     284            0 : }
     285              : //-----------------------------------------------------------------------------
     286              : 
     287              : //-----------------------------------------------------------------------------
     288              : //void
     289              : //FIBIONode::get_info(timinghardwareinfo::TimingFIBMonitorData& mon_data) const
     290              : //{
     291              : 
     292              : //   auto stat_subnodes = read_sub_nodes(getNode("csr.stat"));
     293              : //   auto ctrl_subnodes = read_sub_nodes(getNode("csr.ctrl"));
     294              : 
     295              : //   mon_data.mmcm_ok = stat_subnodes.at("mmcm_ok").value();
     296              : //   mon_data.mmcm_sticky = stat_subnodes.at("mmcm_sticky").value();
     297              :   
     298              : //   mon_data.pll_ok = stat_subnodes.at("pll_ok").value();
     299              : //   mon_data.pll_sticky = stat_subnodes.at("pll_sticky").value();
     300              : 
     301              : //   mon_data.active_sfp_mux = ctrl_subnodes.at("inmux").value();
     302              : 
     303              : //   //mon_data.sfp_los_flags = read_sfp_los_flags();
     304              : //   //mon_data.sfp_fault_flags = read_sfp_fault_flags();
     305              : // }
     306              : //-----------------------------------------------------------------------------
     307              : 
     308              : //-----------------------------------------------------------------------------
     309              : // void
     310              : // FIBIONode::get_info(opmonlib::InfoCollector& ci, int level) const
     311              : // {
     312              : 
     313              : //   if (level >= 2) {
     314              : //     timinghardwareinfo::TimingPLLMonitorData pll_mon_data;
     315              : //     get_pll()->get_info(pll_mon_data);
     316              : //     ci.add(pll_mon_data);
     317              :     
     318              : //     for (uint i=0; i < 8; ++i)
     319              : //     {
     320              : //       opmonlib::InfoCollector sfp_ic;
     321              :       
     322              : //                      std::string sfp_i2c_bus = "i2c_sfp" + std::to_string(i);
     323              : //                      auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
     324              :                               
     325              : //       try
     326              : //       {
     327              : //         sfp->get_info(sfp_ic, level);
     328              : //       }
     329              : //       catch (timing::SFPUnreachable& e)
     330              : //       {
     331              : //         // It is valid that an SFP may not be installed, currently no good way of knowing whether they it should be
     332              : //         TLOG_DEBUG(2) << "Failed to communicate with SFP " << i <<  " on I2C switch channel " << (1UL << i) << " on i2c bus" << m_sfp_i2c_buses.at(0);
     333              : //         continue;
     334              : //       }
     335              : //       ci.add("sfp_"+std::to_string(i),sfp_ic);
     336              : //     }
     337              : //   }
     338              : //   if (level >= 1) {
     339              : //     timinghardwareinfo::TimingFIBMonitorData mon_data;
     340              : //     this->get_info(mon_data);
     341              : //     ci.add(mon_data);
     342              : //   }
     343              : // }
     344              : //-----------------------------------------------------------------------------
     345              : } // namespace timing
     346              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1