LCOV - code coverage report
Current view: top level - flxlibs/src - CardControllerWrapper.cpp (source / functions) Coverage Total Hit
Test: code.result Lines: 0.0 % 116 0
Test Date: 2026-10-11 15:05:20 Functions: 0.0 % 27 0

            Line data    Source code
       1              : /**
       2              :  * @file CardControllerWrapper.cpp
       3              :  *
       4              :  * This is part of the DUNE DAQ , copyright 2020.
       5              :  * Licensing/copyright details are in the COPYING file that you should have
       6              :  * received with this code.
       7              :  */
       8              : // From Module
       9              : #include "CardControllerWrapper.hpp"
      10              : #include "FelixDefinitions.hpp"
      11              : #include "FelixIssues.hpp"
      12              : #include "flxlibs/opmon/CardControllerWrapper.pb.h"
      13              : 
      14              : #include "appmodel/FelixDataSender.hpp"
      15              : #include "appmodel/FelixInterface.hpp"
      16              : #include "logging/Logging.hpp"
      17              : 
      18              : #include "flxcard/FlxException.h"
      19              : 
      20              : #include "fmt/core.h"
      21              : 
      22              : // From STD
      23              : #include <iomanip>
      24              : #include <memory>
      25              : #include <string>
      26              : 
      27              : /**
      28              :  * @brief TRACE debug levels used in this source file
      29              :  */
      30              : enum
      31              : {
      32              :   TLVL_ENTER_EXIT_METHODS = 5,
      33              :   TLVL_WORK_STEPS = 10,
      34              :   TLVL_BOOKKEEPING = 15
      35              : };
      36              : 
      37              : namespace dunedaq {
      38              : namespace flxlibs {
      39              : 
      40            0 : CardControllerWrapper::CardControllerWrapper(uint32_t device_id,
      41              :                                              const appmodel::FelixInterface* flx_cfg,
      42            0 :                                              const std::vector<const appmodel::FelixDataSender*>& flx_senders)
      43            0 :   : m_device_id(device_id)
      44            0 :   , m_flx_cfg(flx_cfg)
      45            0 :   , m_flx_senders(flx_senders)
      46              : {
      47              : 
      48            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper constructor called. Open card " << m_device_id;
      49              : 
      50            0 :   m_flx_card = std::make_unique<FlxCard>();
      51            0 :   if (m_flx_card == nullptr) {
      52            0 :     ers::fatal(flxlibs::CardError(ERS_HERE, "Couldn't create FlxCard object."));
      53              :   }
      54            0 :   open_card();
      55            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper constructed.";
      56            0 : }
      57              : 
      58            0 : CardControllerWrapper::~CardControllerWrapper()
      59              : {
      60            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS)
      61            0 :     << "CardControllerWrapper destructor called. First stop check, then closing card.";
      62            0 :   close_card();
      63            0 :   TLOG_DEBUG(TLVL_ENTER_EXIT_METHODS) << "CardControllerWrapper destroyed.";
      64            0 : }
      65              : 
      66              : void
      67            0 : CardControllerWrapper::init()
      68              : {
      69              : 
      70              :   // Card initialization
      71              :   // this is complicated....should we repeat all code in flx_init?
      72              :   // For now do not do the configs of the clock chips
      73            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
      74            0 :   m_flx_card->cfg_set_option(BF_MMCM_MAIN_LCLK_SEL, 1); // local clock
      75            0 :   m_flx_card->soft_reset();
      76              :   // si5328_configure();
      77              :   // si5345_configure(0);
      78            0 :   m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0xFFFFFFFFFFFF);
      79            0 :   m_flx_card->cfg_set_option(BF_GBT_SOFT_RESET, 0);
      80              : 
      81            0 :   int bad_channels = m_flx_card->gbt_setup(FLX_GBT_ALIGNMENT_ONE, FLX_GBT_TMODE_FEC); // What does this do?
      82            0 :   if (bad_channels) {
      83            0 :     TLOG() << bad_channels << " not aligned.";
      84              :   }
      85            0 :   m_flx_card->irq_disable(ALL_IRQS);
      86            0 : }
      87              : 
      88              : void
      89            0 : CardControllerWrapper::configure(uint16_t super_chunk_size, bool emu_fanout)
      90              : {
      91              :   // Disable all links
      92            0 :   for (size_t i = 0; i < 12; ++i) {
      93              :     // std::stringstream ss;
      94              :     // ss << "DECODING_LINK" << std::setw(2) << std::setfill('0') << i << "_EGROUP0_CTRL_EPATH_ENA";
      95            0 :     set_bitfield(fmt::format("DECODING_LINK{:02}_EGROUP0_CTRL_EPATH_ENA", i), 0);
      96              :   }
      97              : 
      98              :   // Enable/disable emulation
      99            0 :   if (emu_fanout) {
     100              :     // set_bitfield("FE_EMU_LOGIC_IDLES", 0); // FIXME
     101              :     // set_bitfield("FE_EMU_LOGIC_CHUNK_LENGTH", 0);
     102              :     // set_bitfield("FE_EMU_LOGIC_ENA", 0);
     103              :     // set_bitfield("FE_EMU_LOGIC_L1A_TRIGGERED", 0);
     104              : 
     105            0 :     set_bitfield("GBT_TOFRONTEND_FANOUT_SEL", 0);
     106            0 :     set_bitfield("GBT_TOHOST_FANOUT_SEL", 0xffffff);
     107            0 :     set_bitfield("FE_EMU_ENA_EMU_TOFRONTEND", 0);
     108            0 :     set_bitfield("FE_EMU_ENA_EMU_TOHOST", 1);
     109              :   } else {
     110              :     // set_register("FE_EMU_LOGIC_ENA", 0);
     111              :     // set_register("FE_EMU_LOGIC_L1A_TRIGGERED", 0);
     112              :     // set_register("FE_EMU_LOGIC_IDLES", 0);
     113              :     // set_register("FE_EMU_LOGIC_CHUNK_LENGTH", 0);
     114              : 
     115            0 :     set_bitfield("FE_EMU_ENA_EMU_TOFRONTEND", 0);
     116            0 :     set_bitfield("FE_EMU_ENA_EMU_TOHOST", 0);
     117            0 :     set_bitfield("GBT_TOFRONTEND_FANOUT_SEL", 0);
     118            0 :     set_bitfield("GBT_TOHOST_FANOUT_SEL", 0);
     119              :   }
     120              :   // Enable and configure the right links
     121              : 
     122            0 :   for (auto s : m_flx_senders) {
     123            0 :     set_bitfield(fmt::format("SUPER_CHUNK_FACTOR_LINK_{:02}", s->get_link()), super_chunk_size);
     124            0 :     set_bitfield(fmt::format("DECODING_LINK{:02}_EGROUP0_CTRL_EPATH_ENA", s->get_link()), 1);
     125              :   }
     126            0 : }
     127              : 
     128              : void
     129            0 : CardControllerWrapper::open_card()
     130              : {
     131            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Opening FELIX card " << m_device_id;
     132            0 :   try {
     133            0 :     const std::lock_guard<std::mutex> lock(m_card_mutex);
     134            0 :     m_flx_card->card_open(static_cast<int>(m_device_id), LOCK_NONE); // FlxCard.h
     135            0 :   } catch (FlxException& ex) {
     136            0 :     ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
     137            0 :     exit(EXIT_FAILURE);
     138            0 :   }
     139            0 : }
     140              : 
     141              : void
     142            0 : CardControllerWrapper::close_card()
     143              : {
     144            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Closing FELIX card " << m_device_id;
     145            0 :   try {
     146            0 :     const std::lock_guard<std::mutex> lock(m_card_mutex);
     147            0 :     m_flx_card->card_close();
     148            0 :   } catch (FlxException& ex) {
     149            0 :     ers::error(flxlibs::CardError(ERS_HERE, ex.what()));
     150            0 :     exit(EXIT_FAILURE);
     151            0 :   }
     152            0 : }
     153              : 
     154              : uint64_t // NOLINT(build/unsigned)
     155            0 : CardControllerWrapper::get_register(std::string key)
     156              : {
     157            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of register " << key;
     158            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     159            0 :   auto reg_val = m_flx_card->cfg_get_reg(key.c_str());
     160            0 :   return reg_val;
     161            0 : }
     162              : 
     163              : void
     164            0 : CardControllerWrapper::set_register(std::string key, uint64_t value) // NOLINT(build/unsigned)
     165              : {
     166            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of register " << key << " to " << value;
     167            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     168            0 :   m_flx_card->cfg_set_reg(key.c_str(), value);
     169            0 : }
     170              : 
     171              : uint64_t // NOLINT(build/unsigned)
     172            0 : CardControllerWrapper::get_bitfield(std::string key)
     173              : {
     174            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Reading value of bitfield " << key;
     175            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     176            0 :   auto bf_val = m_flx_card->cfg_get_option(key.c_str(), false);
     177            0 :   return bf_val;
     178            0 : }
     179              : 
     180              : void
     181            0 : CardControllerWrapper::set_bitfield(std::string key, uint64_t value) // NOLINT(build/unsigned)
     182              : {
     183            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Setting value of bitfield " << key << " to " << value;
     184            0 :   ;
     185            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     186            0 :   m_flx_card->cfg_set_option(key.c_str(), value, false);
     187            0 : }
     188              : 
     189              : void
     190            0 : CardControllerWrapper::gth_reset()
     191              : {
     192            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Resetting GTH";
     193            0 :   const std::lock_guard<std::mutex> lock(m_card_mutex);
     194            0 :   for (auto i = 0; i < 6; ++i) {
     195            0 :     m_flx_card->gth_rx_reset(i);
     196              :   }
     197            0 : }
     198              : 
     199              : void
     200            0 : CardControllerWrapper::check_alignment(uint64_t aligned)
     201              : {
     202            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Checking link alignment for " << m_flx_cfg->get_slr();
     203              : 
     204            0 :   bool emu_fanout = get_bitfield("FE_EMU_ENA_EMU_TOHOST");
     205              :   // check the alingment on a logical unit
     206            0 :   for (auto s : m_flx_senders) {
     207              :     // here we want to print out a log message when the links do not appear to be aligned.
     208              :     // for WIB readout link_id 5 is always reserved for tp links, so alignemnt is not expected fort these
     209              : #warning FIXME: Horrible remapping workaround. Temporary fix only!
     210            0 :     auto id_to_check = m_flx_cfg->get_slr() * 6 + s->get_link();
     211            0 :     bool is_aligned = aligned & (1 << id_to_check);
     212              :     // auto found_link = std::find(std::begin(alignment_mask), std::end(alignment_mask), li.link_id);
     213              :     // if(found_link == std::end(alignment_mask)) {
     214              :     //   if(!lu_cfg.emu_fanout && !is_aligned) {
     215              :     //     ers::error(flxlibs::ChannelAlignment(ERS_HERE, li.link_id));
     216              :     //   }
     217              :     // }
     218            0 :     if (!emu_fanout && !is_aligned) {
     219            0 :       ers::error(flxlibs::ChannelAlignment(ERS_HERE, s->get_link()));
     220              :     }
     221              :   }
     222            0 : }
     223              : 
     224              : void
     225            0 : CardControllerWrapper::generate_opmon_data()
     226              : {
     227            0 :   TLOG_DEBUG(TLVL_WORK_STEPS) << "Monitoring link alignment for " << m_flx_cfg->get_slr();
     228              : 
     229            0 :   uint64_t aligned = get_register(REG_GBT_ALIGNMENT_DONE);
     230              : 
     231            0 :   for (auto s : m_flx_senders) {
     232              : 
     233            0 :     opmon::LinkInfo i;
     234            0 :     i.set_enabled(true);
     235              : #warning FIXME: Horrible remapping workaround. Temporary fix only!
     236            0 :     auto id_to_check = m_flx_cfg->get_slr() * 6 + s->get_link();
     237            0 :     bool is_aligned = aligned & (1 << id_to_check);
     238            0 :     i.set_aligned(is_aligned);
     239            0 :     publish(std::move(i),
     240            0 :             { { "device", fmt::format("{}", m_device_id) }, { "link", fmt::format("{}", s->get_link()) } });
     241              : 
     242            0 :   } // loop over links
     243            0 : }
     244              : 
     245              : } // namespace flxlibs
     246              : } // namespace dunedaq
        

Generated by: LCOV version 2.0-1