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

            Line data    Source code
       1              : /**
       2              :  * @file GIBIONode.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/GIBIONode.hpp"
      10              : #include "timing/LM75Node.hpp"
      11              : 
      12              : #include <string>
      13              : #include <math.h>
      14              : 
      15              : namespace dunedaq {
      16              : namespace timing {
      17              : 
      18            0 : UHAL_REGISTER_DERIVED_NODE(GIBIONode)
      19              : 
      20              : //-----------------------------------------------------------------------------
      21            0 : GIBIONode::GIBIONode(const uhal::Node& node)
      22            0 :   : IONode(node, "i2c", "i2c", { "PLL" }, { "PLL", "SFP CDR 0", "SFP CDR 1", "SFP CDR 2", "SFP CDR 3", "SFP CDR 4", "SFP CDR 5", "10 MHz" }, { "i2c", "i2c", "i2c", "i2c", "i2c", "i2c" })
      23              : {
      24            0 : }
      25              : //-----------------------------------------------------------------------------
      26              : 
      27              : //-----------------------------------------------------------------------------
      28            0 : GIBIONode::GIBIONode(const uhal::Node& node,
      29              :                std::string uid_i2c_bus,
      30              :                std::string pll_i2c_bus,
      31              :                std::string pll_i2c_device,
      32              :                std::vector<std::string> clock_names,
      33            0 :                std::vector<std::string> sfp_i2c_buses)
      34            0 :   : IONode(node, uid_i2c_bus, pll_i2c_bus, pll_i2c_device, clock_names, sfp_i2c_buses)
      35              : {
      36            0 : }
      37              : //-----------------------------------------------------------------------------
      38              : 
      39              : //-----------------------------------------------------------------------------
      40            0 : GIBIONode::~GIBIONode() {}
      41              : //-----------------------------------------------------------------------------
      42              : 
      43              : //-----------------------------------------------------------------------------
      44              : std::string
      45            0 : GIBIONode::get_uid_address_parameter_name() const
      46              : {
      47            0 :   return "UID_PROM";
      48              : }
      49              : //-----------------------------------------------------------------------------
      50              : 
      51              : //-----------------------------------------------------------------------------
      52              : std::string
      53            0 : GIBIONode::get_status(bool print_out) const
      54              : {
      55            0 :   std::stringstream status;
      56              : 
      57            0 :   auto subnodes = read_sub_nodes(getNode("csr.stat"));
      58            0 :   status << format_reg_table(subnodes, "GIB IO state");
      59              : 
      60            0 :   auto subnodes_2 = read_sub_nodes(getNode("csr.ctrl"));
      61            0 :   status << format_reg_table(subnodes_2, "GIB IO control");
      62              : 
      63            0 :   uint8_t sfp_los = read_sfps_los();
      64            0 :   uint8_t sfp_fault = read_sfps_fault();
      65              : 
      66            0 :   std::vector<std::string> sfp_vec;
      67            0 :   std::vector<uint8_t> los_vec;
      68            0 :   std::vector<uint8_t> fault_vec;
      69              : 
      70            0 :   for (int i=0; i<get_num_sfps(); i++) {
      71            0 :     sfp_vec.push_back(to_string(i));
      72              :     // L is 0x4C, H is L - 4
      73            0 :     los_vec.push_back(0x4C - 4*((sfp_los >> i) & 1));
      74            0 :     fault_vec.push_back(0x4C - 4*((sfp_fault >> i) & 1));
      75              :   }
      76              :   
      77            0 :   status << "------IO expander----" << std::endl;
      78            0 :   status << "SFP:   " << vec_fmt(sfp_vec) << std::endl;
      79            0 :   status << "LOS:   " << vec_fmt(los_vec) << std::endl;
      80            0 :   status << "Fault: " << vec_fmt(fault_vec) << std::endl;
      81              : 
      82            0 :   status << "Board temperature: " << read_board_temperature() << " [C]" << std::endl;
      83              : 
      84            0 :   if (print_out)
      85            0 :     TLOG() << std::endl << status.str();
      86            0 :   return status.str();
      87            0 : }
      88              : //-----------------------------------------------------------------------------
      89              : 
      90              : //-----------------------------------------------------------------------------
      91              : std::unique_ptr<const SI534xSlave>
      92            0 : GIBIONode::get_pll() const
      93              : {
      94              :   // enable pll channel 0 only
      95            0 :   set_i2c_mux_channels(0x1);
      96            0 :   return get_i2c_device<SI534xSlave>(m_pll_i2c_bus, m_pll_i2c_device);
      97              : }
      98              : //-----------------------------------------------------------------------------
      99              : 
     100              : //-----------------------------------------------------------------------------
     101              : std::string
     102            0 : GIBIONode::get_hardware_info(bool print_out) const
     103              : {
     104              :   // enable pll/uid channel 0 only
     105            0 :   set_i2c_mux_channels(0x1);
     106            0 :   return IONode::get_hardware_info(print_out);
     107              : }
     108              : //-----------------------------------------------------------------------------
     109              : 
     110              : //-----------------------------------------------------------------------------
     111              : void
     112            0 : GIBIONode::set_up_io_infrastructure() const
     113              : {
     114              :   // enclustra i2c switch stuff
     115            0 :   CarrierType carrier_type = convert_value_to_carrier_type(read_carrier_type());
     116            0 :   if (carrier_type == kCarrierEnclustraA35) {
     117            0 :     try {
     118            0 :       getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave("AX3_Switch").write_i2c(0x01, 0x7f);
     119            0 :     } catch (const std::exception& e) {
     120            0 :       ers::warning(EnclustraSwitchFailure(ERS_HERE, e));
     121            0 :     }
     122              :   }
     123              : 
     124              :   // Disable ICs
     125              :   //getNode("csr.ctrl.i2c_sw_rst").write(0x1);
     126              :   //getNode("csr.ctrl.i2c_exten_rst").write(0x1);
     127              :   //getNode("csr.ctrl.clk_gen_rst").write(0x1);
     128              :   //getClient().dispatch();
     129              : 
     130              :   // Enable ICs
     131            0 :   getNode("csr.ctrl.i2c_sw_rst").write(0x0);
     132            0 :   getNode("csr.ctrl.i2c_exten_rst").write(0x0);
     133            0 :   getNode("csr.ctrl.clk_gen_rst").write(0x0);
     134            0 :   getClient().dispatch();
     135              : 
     136            0 :   set_i2c_mux_channels(0x1);
     137            0 : }
     138              : //-----------------------------------------------------------------------------
     139              : 
     140              : //-----------------------------------------------------------------------------
     141              : void
     142            0 : GIBIONode::reset(const std::string& clock_config_file) const
     143              : {
     144              :   // Clear IPBus regs
     145            0 :   soft_reset();
     146              : 
     147              :   // In case this method is called directly, TODO refactor
     148            0 :   set_up_io_infrastructure();
     149              : 
     150            0 :   getNode("csr.ctrl.gps_clk_en").write(0x0);
     151              : 
     152              :   // Set filter to full bandwidth mode A = B = 0x0
     153            0 :   getNode("csr.ctrl.gps_clk_fltr_a").write(0x0);
     154            0 :   getNode("csr.ctrl.gps_clk_fltr_b").write(0x0);
     155            0 :   getClient().dispatch();
     156              : 
     157              :   // Upload config file to PLL
     158            0 :   configure_pll(clock_config_file);
     159              : 
     160            0 :   configure_expander();
     161              : 
     162              :   // reset dts logic
     163            0 :   getNode("csr.ctrl.rst").write(0x1);
     164            0 :   getClient().dispatch();
     165            0 :   getNode("csr.ctrl.rst").write(0x0);
     166            0 :   getClient().dispatch();
     167              : 
     168            0 :   TLOG() << "Reset done";
     169            0 : }
     170              : //-----------------------------------------------------------------------------
     171              : 
     172              : //-----------------------------------------------------------------------------
     173              : void
     174            0 : GIBIONode::configure_expander() const
     175              : {
     176            0 :   auto sfp_expander_0 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander0");
     177            0 :   auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
     178              :   
     179              :   // Set invert registers to default for both (0,1) banks
     180            0 :   sfp_expander_0->set_inversion(0, 0x00);
     181            0 :   sfp_expander_0->set_inversion(1, 0x00);
     182            0 :   sfp_expander_1->set_inversion(0, 0x00);
     183            0 :   sfp_expander_1->set_inversion(1, 0x00);
     184              :   
     185              :   // 0: pin set as output, 1: pin set as input
     186            0 :   sfp_expander_0->set_io(0, 0xff); // set all pins of bank 0 as inputs
     187            0 :   sfp_expander_0->set_io(1, 0xff); // set all pins of bank 1 as inputs
     188              : 
     189            0 :   sfp_expander_1->set_io(0, 0xff); // set all pins of bank 0 as inputs
     190            0 :   sfp_expander_1->set_io(1, 0x00); // set all pins of bank 1 as outputs
     191              : 
     192              :   // Set SFP disable 
     193              :   // Set tx disable pins low, i.e. enable the pins given in the bitmap
     194              :   //   (different between v1 and v2/3)
     195            0 :   sfp_expander_1->set_outputs(1, get_sfp_tx_disable_bitmap());
     196            0 : }
     197              : //-----------------------------------------------------------------------------
     198              : 
     199              : //-----------------------------------------------------------------------------
     200              : void
     201            0 : GIBIONode::reset_pll() const
     202              : {
     203            0 :   getNode("csr.ctrl.clk_gen_rst").write(0x1);
     204            0 :   getNode("csr.ctrl.clk_gen_rst").write(0x0);
     205            0 : }
     206              : //-----------------------------------------------------------------------------
     207              : 
     208              : //-----------------------------------------------------------------------------
     209              : std::string
     210            0 : GIBIONode::get_sfp_status(uint32_t sfp_id, bool print_out) const { // NOLINT(build/unsigned)
     211            0 :   std::stringstream status;
     212              :   
     213            0 :   validate_sfp_id(sfp_id);
     214              : 
     215            0 :   uint8_t i2c_mux_bitmask = 1UL << (sfp_id+1);
     216              : 
     217            0 :   set_i2c_mux_channels(i2c_mux_bitmask);
     218              : 
     219            0 :   auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
     220              : 
     221            0 :   status << "SFP " << sfp_id << ":" << std::endl;
     222            0 :   status << sfp->get_status();
     223              : 
     224            0 :   if (print_out)
     225            0 :     TLOG() << status.str();
     226              : 
     227            0 :   return status.str();
     228            0 : }
     229              : //-----------------------------------------------------------------------------
     230              : 
     231              : //-----------------------------------------------------------------------------
     232              : uint32_t
     233            0 : GIBIONode::read_io_expanders() const { // NOLINT(build/unsigned)
     234            0 :   auto sfp_expander_0 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander0");
     235            0 :   auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
     236              : 
     237            0 :   uint32_t expander_bits = sfp_expander_1->read_inputs(0);
     238            0 :   expander_bits = (expander_bits << 8) + sfp_expander_0->read_inputs(1);
     239            0 :   expander_bits = (expander_bits << 8) + sfp_expander_0->read_inputs(0);
     240              : 
     241            0 :   return expander_bits;
     242            0 : }
     243              : //-----------------------------------------------------------------------------
     244              : 
     245              : //-----------------------------------------------------------------------------
     246              : uint8_t
     247            0 : GIBIONode::read_sfps_los() const { // NOLINT(build/unsigned)
     248            0 :   uint32_t expander_bits = read_io_expanders();
     249              : 
     250            0 :   uint8_t los_bits = 0x00;
     251              : 
     252            0 :   for (uint8_t sfp = 0; sfp<6; sfp++) {
     253              :     // Each SFP has 4 bits, the 3rd bit is the LOS
     254              :     // Adds the SFPs in inverse order
     255            0 :     los_bits = (los_bits << 1) + ((expander_bits >> (2 + 20 - 4*sfp)) & 1);
     256              :   }
     257              : 
     258            0 :   return los_bits;
     259              : }
     260              : //-----------------------------------------------------------------------------
     261              : 
     262              : //-----------------------------------------------------------------------------
     263              : uint8_t
     264            0 : GIBIONode::read_sfps_fault() const { // NOLINT(build/unsigned)
     265            0 :   uint32_t expander_bits = read_io_expanders();
     266              : 
     267            0 :   uint8_t fault_bits = 0x00;
     268              : 
     269            0 :   for (uint8_t sfp = 0; sfp<6; sfp++) {
     270              :     // Each SFP has 4 bits, the 4th bit is the fault
     271              :     // Adds the SFPs in inverse order
     272            0 :     fault_bits = (fault_bits << 1) + ((expander_bits >> (3 + 20 - 4*sfp)) & 1);
     273              :   }
     274              : 
     275            0 :   return fault_bits;
     276              : }
     277              : //-----------------------------------------------------------------------------
     278              : 
     279              : //-----------------------------------------------------------------------------
     280              : bool
     281            0 : GIBIONode::clocks_ok() const
     282              : {
     283            0 :   std::stringstream status;
     284              : 
     285            0 :   auto states = read_sub_nodes(getNode("csr.stat"));
     286            0 :   bool pll_lol = states.find("clk_gen_lol")->second.value();
     287            0 :   bool pll_interrupt = states.find("clk_gen_intr")->second.value();
     288            0 :   bool mmcm_ok = states.find("mmcm_ok")->second.value();
     289            0 :   bool mmcm_10_ok = states.find("mmcm_ok")->second.value();
     290              : 
     291            0 :   TLOG_DEBUG(5) << "pll lol: " << pll_lol << ", pll intr: " << pll_interrupt
     292            0 :                 << ", mmcm ok: " << mmcm_ok << ", mmcm 10MHz ok: " << mmcm_10_ok;
     293              : 
     294            0 :   return !pll_lol && mmcm_ok && mmcm_10_ok;
     295            0 : }
     296              : //-----------------------------------------------------------------------------
     297              : 
     298              : //-----------------------------------------------------------------------------
     299              : void
     300            0 : GIBIONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
     301            0 :   validate_sfp_id(sfp_id);
     302              : 
     303            0 :   auto sfp = get_i2c_device<I2CSFPSlave>(m_sfp_i2c_buses.at(sfp_id), "SFP_EEProm");
     304            0 :   sfp->switch_soft_tx_control_bit(turn_on);
     305            0 : }
     306              : //-----------------------------------------------------------------------------
     307              : 
     308              : //-----------------------------------------------------------------------------
     309              : void
     310            0 : GIBIONode::switch_sfp_tx(uint32_t sfp_id, bool turn_on) const { // NOLINT(build/unsigned)
     311            0 :         validate_sfp_id(sfp_id);
     312              : 
     313            0 :   auto sfp_expander_1 = get_i2c_device<I2CExpanderSlave>(m_uid_i2c_bus, "SFPExpander1");
     314            0 :         uint8_t current_sfp_tx_control_flags = sfp_expander_1->read_outputs_config(1); // NOLINT(build/unsigned)
     315              : 
     316            0 :         uint8_t new_sfp_tx_control_flags; // NOLINT(build/unsigned)
     317            0 :         if (turn_on)
     318              :         {
     319            0 :                 new_sfp_tx_control_flags = current_sfp_tx_control_flags & ~(1UL << sfp_id);
     320              :         }
     321              :   else
     322              :   {
     323            0 :     new_sfp_tx_control_flags = current_sfp_tx_control_flags | (1UL << sfp_id);
     324              :   }
     325              : 
     326            0 :   sfp_expander_1->set_outputs(1, new_sfp_tx_control_flags);
     327            0 : }
     328              : //-----------------------------------------------------------------------------
     329              : 
     330              : //-----------------------------------------------------------------------------
     331              : //void
     332              : //GIBIONode::get_info(timinghardwareinfo::TimingGIBMonitorData& mon_data) const
     333              : //{
     334              :   // TODO
     335              : //}
     336              : //-----------------------------------------------------------------------------
     337              : 
     338              : //-----------------------------------------------------------------------------
     339              : // void
     340              : // GIBIONode::get_info(opmonlib::InfoCollector& /*ci*/, int /*level*/) const
     341              : // {
     342              : //   // TO DO
     343              : // }
     344              : //-----------------------------------------------------------------------------
     345              : 
     346              : //-----------------------------------------------------------------------------
     347              : uint8_t
     348            0 : GIBIONode::get_sfp_tx_disable_bitmap() const { // NOLINT(build/unsigned)
     349              :   // First 6 bits are tx disable on GIBv1
     350            0 :   return 0xC0;
     351              : }
     352              : //-----------------------------------------------------------------------------
     353              : 
     354              : //-----------------------------------------------------------------------------
     355              : uint8_t
     356            0 : GIBIONode::get_num_sfps() const { // NOLINT(build/unsigned)
     357              :   // 6 SFPs on GIBv1
     358            0 :   return 6;
     359              : }
     360              : //-----------------------------------------------------------------------------
     361              : 
     362              : //-----------------------------------------------------------------------------
     363              : void
     364            0 : GIBIONode::validate_sfp_id(uint32_t sfp_id) const { // NOLINT(build/unsigned)
     365              :   // number of sfps on board defined by get_num_sfps
     366            0 :   if (sfp_id >= get_num_sfps()) {
     367            0 :         throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id));
     368              :   }
     369            0 : }
     370              : //-----------------------------------------------------------------------------
     371              : 
     372              : //-----------------------------------------------------------------------------
     373              : void
     374            0 : GIBIONode::set_i2c_mux_channels(uint8_t mux_channel_bitmask) const { // NOLINT(build/unsigned)
     375              : 
     376            0 :   uint8_t mux_channel_config = mux_channel_bitmask & 0x7f;
     377              :   
     378            0 :   auto i2c_bus = getNode<I2CMasterNode>("i2c");
     379            0 :   i2c_bus.write_i2cPrimitive(0x70, {mux_channel_config});
     380            0 : }
     381              : //-----------------------------------------------------------------------------
     382              : 
     383              : //-----------------------------------------------------------------------------
     384              : float
     385            0 : GIBIONode::read_board_temperature() const
     386              : {
     387            0 :         auto temp_mon = get_i2c_device<LM75Node>(m_pll_i2c_bus, "TEMP_MON");
     388            0 :         return temp_mon->read_temperature();
     389            0 : }
     390              : //-----------------------------------------------------------------------------
     391              : } // namespace timing
     392              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1