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

            Line data    Source code
       1              : /**
       2              :  * @file IONode.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/IONode.hpp"
      10              : 
      11              : #include "logging/Logging.hpp"
      12              : 
      13              : #include <map>
      14              : #include <memory>
      15              : #include <string>
      16              : #include <utility>
      17              : #include <vector>
      18              : 
      19              : namespace dunedaq {
      20              : namespace timing {
      21              : 
      22              : // UHAL_REGISTER_DERIVED_NODE(IONode);
      23              : 
      24              : //-----------------------------------------------------------------------------
      25            0 : IONode::IONode(const uhal::Node& node,
      26              :                std::string uid_i2c_bus,
      27              :                std::string pll_i2c_bus,
      28              :                std::string pll_i2c_device,
      29              :                std::vector<std::string> clock_names,
      30            0 :                std::vector<std::string> sfp_i2c_buses)
      31              :   : TimingNode(node)
      32            0 :   , m_uid_i2c_bus(uid_i2c_bus)
      33            0 :   , m_pll_i2c_bus(pll_i2c_bus)
      34            0 :   , m_pll_i2c_device(pll_i2c_device)
      35            0 :   , m_clock_names(clock_names)
      36            0 :   , m_sfp_i2c_buses(sfp_i2c_buses)
      37              : // mPLL (new SI534xSlave( getNode<I2CMasterNode>(m_pll_i2c_bus)& ,
      38              : // getNode<I2CMasterNode>(m_pll_i2c_bus).get_slave_address(pll_i2c_device) ))
      39            0 : {}
      40              : //-----------------------------------------------------------------------------
      41              : 
      42              : //-----------------------------------------------------------------------------
      43            0 : IONode::~IONode() {}
      44              : //-----------------------------------------------------------------------------
      45              : 
      46              : //-----------------------------------------------------------------------------
      47              : uint32_t // NOLINT(build/unsigned)
      48            0 : IONode::read_board_type() const
      49              : {
      50            0 :   uhal::ValWord<uint32_t> board_type = getNode("config.board_type").read(); // NOLINT(build/unsigned)
      51            0 :   getClient().dispatch();
      52            0 :   return board_type.value();
      53            0 : }
      54              : //-----------------------------------------------------------------------------
      55              : 
      56              : //-----------------------------------------------------------------------------
      57              : uint32_t // NOLINT(build/unsigned)
      58            0 : IONode::read_carrier_type() const
      59              : {
      60            0 :   uhal::ValWord<uint32_t> carrier_type = getNode("config.carrier_type").read(); // NOLINT(build/unsigned)
      61            0 :   getClient().dispatch();
      62            0 :   return carrier_type.value();
      63            0 : }
      64              : //-----------------------------------------------------------------------------
      65              : 
      66              : //-----------------------------------------------------------------------------
      67              : uint32_t // NOLINT(build/unsigned)
      68            0 : IONode::read_design_type() const
      69              : {
      70            0 :   uhal::ValWord<uint32_t> design_type = getNode("config.design_type").read(); // NOLINT(build/unsigned)
      71            0 :   getClient().dispatch();
      72            0 :   return design_type.value();
      73            0 : }
      74              : //-----------------------------------------------------------------------------
      75              : 
      76              : //-----------------------------------------------------------------------------
      77              : uint32_t // NOLINT(build/unsigned)
      78            0 : IONode::read_firmware_frequency() const
      79              : {
      80            0 :   uhal::ValWord<uint32_t> firmware_frequency = getNode("config.clock_frequency").read(); // NOLINT(build/unsigned)
      81            0 :   getClient().dispatch();
      82            0 :   return firmware_frequency.value();
      83            0 : }
      84              : //-----------------------------------------------------------------------------
      85              : 
      86              : //-----------------------------------------------------------------------------
      87              : uint64_t // NOLINT(build/unsigned)
      88            0 : IONode::read_board_uid() const
      89              : {
      90              : 
      91            0 :   uint64_t uid = 0;                // NOLINT(build/unsigned)
      92            0 :   std::vector<uint8_t> uid_values = // NOLINT(build/unsigned)
      93            0 :     getNode<I2CMasterNode>(m_uid_i2c_bus).get_slave(get_uid_address_parameter_name()).read_i2cArray(0xfa, 6);
      94              : 
      95            0 :   for (uint8_t i = 0; i < uid_values.size(); ++i) { // NOLINT(build/unsigned)
      96            0 :     uid = (uid << 8) | uid_values.at(i);
      97              :   }
      98            0 :   return uid;
      99            0 : }
     100              : //-----------------------------------------------------------------------------
     101              : 
     102              : //-----------------------------------------------------------------------------
     103              : BoardRevision
     104            0 : IONode::get_board_revision() const
     105              : {
     106            0 :   auto uid = read_board_uid();
     107            0 :   try {
     108            0 :     return get_board_uid_revision_map().at(uid);
     109            0 :   } catch (const std::out_of_range& e) {
     110            0 :     ers::warning(UnknownBoardUID(ERS_HERE, format_reg_value(uid), e));
     111            0 :     return kBoardRevisionUnknown;
     112            0 :   }
     113              : }
     114              : //-----------------------------------------------------------------------------
     115              : 
     116              : //-----------------------------------------------------------------------------
     117              : std::string
     118            0 : IONode::get_hardware_info(bool print_out) const
     119              : {
     120            0 :   std::stringstream info;
     121            0 :   const BoardType board_type = convert_value_to_board_type(read_board_type());
     122            0 :   const BoardRevision board_revision = get_board_revision();
     123            0 :   const CarrierType carrier_type = convert_value_to_carrier_type(read_carrier_type());
     124            0 :   const DesignType design_type = convert_value_to_design_type(read_design_type());
     125            0 :   const double firmware_frequency = read_firmware_frequency()/1e6;
     126              : 
     127            0 :   std::vector<std::pair<std::string, std::string>> hardware_info;
     128              : 
     129            0 :   try {
     130            0 :     hardware_info.push_back(std::make_pair("Board type", get_board_type_map().at(board_type)));
     131            0 :   } catch (const std::out_of_range& e) {
     132            0 :     ers::error(MissingBoardTypeMapEntry(ERS_HERE, format_reg_value(board_type), e));
     133            0 :   }
     134              : 
     135            0 :   try {
     136            0 :     hardware_info.push_back(std::make_pair("Board revision", get_board_revision_map().at(board_revision)));
     137            0 :   } catch (const std::out_of_range& e) {
     138            0 :     ers::error(MissingBoardRevisionMapEntry(ERS_HERE, format_reg_value(board_revision), e));
     139            0 :   }
     140              : 
     141            0 :   hardware_info.push_back(std::make_pair("Board UID", format_reg_value(read_board_uid())));
     142              : 
     143            0 :   try {
     144            0 :     hardware_info.push_back(std::make_pair("Carrier type", get_carrier_type_map().at(carrier_type)));
     145            0 :   } catch (const std::out_of_range& e) {
     146            0 :     ers::error(MissingCarrierTypeMapEntry(ERS_HERE, format_reg_value(carrier_type), e));
     147            0 :   }
     148              : 
     149            0 :   try {
     150            0 :     hardware_info.push_back(std::make_pair("Design type", get_design_type_map().at(design_type)));
     151            0 :   } catch (const std::out_of_range& e) {
     152            0 :     ers::error(MissingDesignTypeMapEntry(ERS_HERE, format_reg_value(design_type), e));
     153            0 :   }
     154              : 
     155            0 :   hardware_info.push_back(std::make_pair("Firmware frequency [MHz]", std::to_string(firmware_frequency)));
     156              : 
     157            0 :   info << format_reg_table(hardware_info, "Hardware info", { "", "" });
     158              : 
     159            0 :   if (print_out)
     160            0 :     TLOG() << info.str();
     161            0 :   return info.str();
     162            0 : }
     163              : //-----------------------------------------------------------------------------
     164              : 
     165              : //-----------------------------------------------------------------------------
     166              : std::string
     167            0 : IONode::get_full_clock_config_file_path(const ClockSource& clock_source) const
     168              : {
     169            0 :   std::string config_file;
     170            0 :   std::stringstream clock_config_key;
     171              : 
     172            0 :   const BoardType board_type = convert_value_to_board_type(read_board_type());
     173              : //    const BoardRevision board_revision = get_board_revision();
     174            0 :   const CarrierType carrier_type = convert_value_to_carrier_type(read_carrier_type());
     175            0 :   const DesignType design_type = convert_value_to_design_type(read_design_type());
     176              :   //const uint32_t firmware_frequency = read_firmware_frequency(); // NOLINT(build/unsigned)
     177              : 
     178            0 :   try {
     179            0 :     clock_config_key << get_board_type_map().at(board_type) << "_";
     180            0 :   } catch (const std::out_of_range& e) {
     181            0 :     throw MissingBoardTypeMapEntry(ERS_HERE, format_reg_value(board_type), e);
     182            0 :   }
     183              : 
     184            0 :   auto pll = get_pll();
     185            0 :   auto pll_model = pll->read_device_version();
     186            0 :   clock_config_key << std::hex << pll_model;
     187              : 
     188              : //    try {
     189              : //      clock_config_key = clock_config_key + get_carrier_type_map().at(carrier_type) + "_";
     190              : //    } catch (const std::out_of_range& e) {
     191              : //      throw MissingCarrierTypeMapEntry(ERS_HERE, format_reg_value(carrier_type), e);
     192              : //    }
     193              : 
     194            0 :   try {
     195            0 :     clock_config_key << "_" << get_design_type_map().at(design_type);
     196            0 :   } catch (const std::out_of_range& e) {
     197            0 :     throw MissingDesignTypeMapEntry(ERS_HERE, format_reg_value(design_type), e);
     198            0 :   }
     199              : 
     200            0 :   clock_config_key << "_" << clock_source_to_string(clock_source);
     201              : 
     202            0 :   TLOG_DEBUG(0) << "Using pll config key: " << clock_config_key.str();
     203              : 
     204            0 :   try {
     205            0 :     config_file = get_clock_config_map().at(clock_config_key.str());
     206            0 :   } catch (const std::out_of_range& e) {
     207            0 :     throw ClockConfigNotFound(ERS_HERE, clock_config_key.str(), e);
     208            0 :   }
     209              : 
     210            0 :   TLOG_DEBUG(0) << "PLL config file: " << config_file << " from key: " << clock_config_key.str();
     211              : 
     212            0 :   const char* env_var_char = std::getenv("TIMING_SHARE");
     213              : 
     214            0 :   if (env_var_char == nullptr) {
     215            0 :     throw EnvironmentVariableNotSet(ERS_HERE, "TIMING_SHARE");
     216              :   }
     217              : 
     218            0 :   std::string env_var(env_var_char);
     219              : 
     220            0 :   std::string full_pll_config_file_path = env_var + "/config/etc/clock/" + config_file;
     221              : 
     222            0 :   TLOG_DEBUG(0) << "Full PLL config file path: " << full_pll_config_file_path;
     223              : 
     224            0 :   return full_pll_config_file_path;
     225            0 : }
     226              : //-----------------------------------------------------------------------------
     227              : 
     228              : //-----------------------------------------------------------------------------
     229              : std::unique_ptr<const SI534xSlave>
     230            0 : IONode::get_pll() const
     231              : {
     232            0 :   return get_i2c_device<SI534xSlave>(m_pll_i2c_bus, m_pll_i2c_device);
     233              : }
     234              : //-----------------------------------------------------------------------------
     235              : 
     236              : //-----------------------------------------------------------------------------
     237              : void
     238            0 : IONode::configure_pll(const std::string& clock_config_file) const
     239              : {
     240            0 :   auto pll = get_pll();
     241              : 
     242            0 :   TLOG() << "PLL configuration file : " << clock_config_file;
     243              : 
     244            0 :   uint32_t si_pll_version = pll->read_device_version(); // NOLINT(build/unsigned)
     245            0 :   TLOG_DEBUG(0) << "Configuring PLL        : SI" << format_reg_value(si_pll_version);
     246              : 
     247            0 :   pll->configure(clock_config_file);
     248              : 
     249            0 :   TLOG_DEBUG(0) << "PLL configuration id   : " << pll->read_config_id();
     250            0 : }
     251              : //-----------------------------------------------------------------------------
     252              : 
     253              : //-----------------------------------------------------------------------------
     254              : std::vector<double>
     255            0 : IONode::read_clock_frequencies() const
     256              : {
     257            0 :   return getNode<FrequencyCounterNode>("freq").measure_frequencies(m_clock_names.size());
     258              : }
     259              : //-----------------------------------------------------------------------------
     260              : 
     261              : //-----------------------------------------------------------------------------
     262              : std::string
     263            0 : IONode::get_clock_frequencies_table(bool print_out) const
     264              : {
     265            0 :   std::stringstream table;
     266            0 :   std::vector<double> frequencies = read_clock_frequencies();
     267            0 :   for (uint8_t i = 0; i < frequencies.size(); ++i) { // NOLINT(build/unsigned)
     268            0 :     table << m_clock_names.at(i) << " freq: " << std::setprecision(12) << frequencies.at(i) << std::endl;
     269              :   }
     270              :   // TODO add freq validation Stoyan Trilov stoyan.trilov@cern.ch
     271            0 :   if (print_out)
     272            0 :     TLOG() << table.str();
     273            0 :   return table.str();
     274            0 : }
     275              : //-----------------------------------------------------------------------------
     276              : 
     277              : //-----------------------------------------------------------------------------
     278              : std::string
     279            0 : IONode::get_pll_status(bool print_out) const
     280              : {
     281            0 :   return get_pll()->get_status(print_out);
     282              : }
     283              : //-----------------------------------------------------------------------------
     284              : 
     285              : //-----------------------------------------------------------------------------
     286              : void
     287            0 : IONode::write_soft_reset_register() const
     288              : {
     289            0 :   getNode("csr.ctrl.soft_rst").write(0x1);
     290            0 :   getClient().dispatch();
     291            0 : }
     292              : //-----------------------------------------------------------------------------
     293              : 
     294              : //-----------------------------------------------------------------------------
     295              : void
     296            0 : IONode::soft_reset() const
     297              : {
     298            0 :   write_soft_reset_register();
     299            0 :   TLOG_DEBUG(0) << "Soft reset done";
     300            0 : }
     301              : //-----------------------------------------------------------------------------
     302              : 
     303              : //-----------------------------------------------------------------------------
     304              : void
     305            0 : IONode::reset(const ClockSource& clock_source) const
     306              : {
     307            0 :   TLOG() << "Setting IO preliminaries: I2C access, etc..";
     308            0 :   set_up_io_infrastructure();
     309              : 
     310              :   // Find the right pll config file
     311            0 :   std::string clock_config = get_full_clock_config_file_path(clock_source);
     312            0 :   reset(clock_config);
     313            0 : }
     314              : //-----------------------------------------------------------------------------
     315              : 
     316              : //-----------------------------------------------------------------------------
     317              : std::string
     318            0 : IONode::get_sfp_status(uint32_t sfp_id, bool print_out) const // NOLINT(build/unsigned)
     319              : {
     320            0 :   std::stringstream status;
     321            0 :   std::string sfp_i2c_bus;
     322            0 :   try {
     323            0 :     sfp_i2c_bus = m_sfp_i2c_buses.at(sfp_id);
     324            0 :   } catch (const std::out_of_range& e) {
     325            0 :     throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id), e);
     326            0 :   }
     327            0 :   auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
     328            0 :   status << sfp->get_status();
     329            0 :   if (print_out)
     330            0 :     TLOG() << status.str();
     331            0 :   return status.str();
     332            0 : }
     333              : //-----------------------------------------------------------------------------
     334              : 
     335              : //-----------------------------------------------------------------------------
     336              : void
     337            0 : IONode::switch_sfp_soft_tx_control_bit(uint32_t sfp_id, bool turn_on) const // NOLINT(build/unsigned)
     338              : {
     339            0 :   std::string sfp_i2c_bus;
     340            0 :   try {
     341            0 :     sfp_i2c_bus = m_sfp_i2c_buses.at(sfp_id);
     342            0 :   } catch (const std::out_of_range& e) {
     343            0 :     throw InvalidSFPId(ERS_HERE, format_reg_value(sfp_id), e);
     344            0 :   }
     345            0 :   auto sfp = get_i2c_device<I2CSFPSlave>(sfp_i2c_bus, "SFP_EEProm");
     346            0 :   sfp->switch_soft_tx_control_bit(turn_on);
     347            0 : }
     348              : //-----------------------------------------------------------------------------
     349              : 
     350              : } // namespace timing
     351              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1